Create Global Function and Class

I

Immortal Nephi

I need to follow best practice guideline how to design my code
correctly. I have to decide which either global function or class can
be chosen.
I will use global function if global function is available to all
file scopes or is in namespace scope. I need to avoid data
modification when necessary.
I can write good global function.

int gFunc( int x, int y ) {
// Do something
// ….

return z;
}

If I have to modify either x or y in the function parameter, I will
put const in function parameter or create temporary variable.

int gFunc( const int x, const int y ) {
// Do something
// ….

return z;
}

// or…

int gFunc( int x, int y ) {
int temp_x = x;
int temp_y = y;

// Do something
// ….

return z;
}

If I want to put character buffer (like string) or class name in the
function parameter, I will need to put reference in it to avoid
overhead of copying each data size. Also, I will remember to put
const before reference if necessary.

class Object {

int x;
int y;
int z;
}

Object gFunc( const Object& obj ) {
Object temp_obj;

// Do something
// ….

return temp_obj;
}

The return type requires to create temporary object before all data
members in class Object is copied and temp_obj is destroyed from the
stack.

Tell me why you have reason to add reference to the return type.

class Data {
int x;
int y;
int z;
};

class Object {
Data m_Data;

Data &DoSomething() {
// Do something
return m_Data;
}
};

Notice DoSomething has reference return type. Do you need to use
reference return type? If yes, what is it used for?
Maybe, you want to suggest your code to explain why you need
reference return type. Reference return type is dangerous unless you
use return ‘this’ pointer.
 
F

Francesco S. Carta

I need to follow best practice guideline how to design my code
correctly. I have to decide which either global function or class can
be chosen.
I will use global function if global function is available to all
file scopes or is in namespace scope. I need to avoid data
modification when necessary.
I can write good global function.

int gFunc( int x, int y ) {
// Do something
// ….

return z;
}

If I have to modify either x or y in the function parameter, I will
put const in function parameter or create temporary variable.

int gFunc( const int x, const int y ) {
// Do something
// ….

return z;
}

// or…

int gFunc( int x, int y ) {
int temp_x = x;
int temp_y = y;

// Do something
// ….

return z;
}

If I want to put character buffer (like string) or class name in the
function parameter, I will need to put reference in it to avoid
overhead of copying each data size. Also, I will remember to put
const before reference if necessary.

class Object {

int x;
int y;
int z;
}

Object gFunc( const Object& obj ) {
Object temp_obj;

// Do something
// ….

return temp_obj;
}

The return type requires to create temporary object before all data
members in class Object is copied and temp_obj is destroyed from the
stack.

Tell me why you have reason to add reference to the return type.

Anytime you need to pass something by reference. That's that simple.
class Data {
int x;
int y;
int z;
};

class Object {
Data m_Data;

Data&DoSomething() {
// Do something
return m_Data;
}
};

Notice DoSomething has reference return type. Do you need to use
reference return type? If yes, what is it used for?

It depends on the cases, sometimes you need it, sometimes you don't.
It's impossible to create objective absolute rules about all of this stuff.

In C++ there is a quite peculiar case, though: iostreams are (always?)
passed and returned by non-const reference. Somebody else will
articulate this point, eventually.
Maybe, you want to suggest your code to explain why you need
reference return type. Reference return type is dangerous unless you
use return ‘this’ pointer.

The "dangerousness" of returning a reference is absolutely not related
to the fact of returning a reference to "*this".

The most dangerous case is when you return a reference (or a pointer) to
a local non static variable, which very likely amounts to looking for
trouble.

Further than that, all this discourse is too vague to be of any use.

Pick a practical non-abstract example and implement it as you find it
more correct, then we could discuss the various approaches.
 
V

Victor Bazarov

[..]
In C++ there is a quite peculiar case, though: iostreams are (always?)
passed and returned by non-const reference. Somebody else will
articulate this point, eventually.

Chaining calls is one reason why you want to return a reference. For
instance, it's easier to write

foo.DoSomething().DoSomethingElse().DoMore();

than

foo.DoSomething();
foo.DoSomethingElse();
foo.DoMore();

IMO. Especially if you have specific patterns that call for such
sequences of calls, and you don't need to check error conditions between
them, blah blah...

V
 
J

James Kanze

I need to follow best practice guideline how to design my code
correctly. I have to decide which either global function or class can
be chosen.
I will use global function if global function is available to all
file scopes or is in namespace scope. I need to avoid data
modification when necessary.
I can write good global function.
int gFunc( int x, int y ) {
// Do something
// ….

return z;
}
If I have to modify either x or y in the function parameter, I will
put const in function parameter or create temporary variable.
int gFunc( const int x, const int y ) {

Note that the const above does not affect the function signature
(the client view of the function) in any way.
// Do something
// ….

return z;
}
int gFunc( int x, int y ) {
int temp_x = x;
int temp_y = y;

Not sure what you're trying to accomplish with the temporaries.
You'll have to explain yourself more clearly.
// Do something
// ….
return z;
}
If I want to put character buffer (like string) or class name in the
function parameter, I will need to put reference in it to avoid
overhead of copying each data size.

Maybe. It's a common convention, anyway.
Also, I will remember to put const before reference if
necessary.
class Object {
int x;
int y;
int z;
}
Object gFunc( const Object& obj ) {
Object temp_obj;

// Do something
// ….

return temp_obj;
}
The return type requires to create temporary object before all data
members in class Object is copied and temp_obj is destroyed from the
stack.
Tell me why you have reason to add reference to the return type.

Because you want to return a reference to an existing object,
rather than a new object. The classical example is
std::vector<>::eek:perator[]. (If it is a search function which
can fail, you might prefer returning a pointer, with a null
pointer for failure.)
class Data {
int x;
int y;
int z;
};
class Object {
Data m_Data;
Data &DoSomething() {
// Do something
return m_Data;
}
};
Notice DoSomething has reference return type. Do you need to use
reference return type? If yes, what is it used for?

It's used to allow the client access to the actual object.
Maybe, you want to suggest your code to explain why you need
reference return type. Reference return type is dangerous unless you
use return ‘this’ pointer.

Reference return types are necessary for some things to work.
 
J

James Kanze

[...]
In C++ there is a quite peculiar case, though: iostreams are (always?)
passed and returned by non-const reference. Somebody else will
articulate this point, eventually.

As Victor has pointed out, this is to support chaining. It's
worth mentionning, however, that iostream's aren't copyable, so
they can't be returned by value.
 
F

Francesco S. Carta

[...]
In C++ there is a quite peculiar case, though: iostreams are (always?)
passed and returned by non-const reference. Somebody else will
articulate this point, eventually.

As Victor has pointed out, this is to support chaining. It's
worth mentionning, however, that iostream's aren't copyable, so
they can't be returned by value.

Ah, right, so iostreams are always passed by reference (or by pointer).

In any case, saying that return by reference "is to support chaining"
looks limiting (even though it isn't). That's just one of its uses.

Besides, even return by pointer supports chaining, it just requires the
"->" notation instead of the "." notation, in a case like the one
pointed out by Victor.

Admittedly, the case of chained insertions and chained extractions for
streams is made possible with the return by reference in particular.
 
Ö

Öö Tiib

        The return type requires to create temporary object before all data
members in class Object is copied and temp_obj is destroyed from the
stack.

        Tell me why you have reason to add reference to the return type.

class Data {
        int x;
        int y;
        int z;

};

class Object {
        Data m_Data;

        Data &DoSomething() {
                // Do something
                return m_Data;
        }

};

        Notice DoSomething has reference return type.  Do you need to use
reference return type?  If yes, what is it used for?
        Maybe, you want to suggest your code to explain why you need
reference return type.  Reference return type is dangerous unless you
use return ‘this’ pointer.

Very lot of objects are not copyable. Think about yourself. How i make
a copy of you? Copying sounds like nonsense. I can only copy some
documents about you. Software usually tries to make an abstract model
of problem situation within computer. So copying abstractions of
really not copyable objects is made often impossible in software too.
Software has to pass and return these like pointers or references. You
can not return as values, it must be thinkable to copy something to
return it by value.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,967
Messages
2,570,148
Members
46,694
Latest member
LetaCadwal

Latest Threads

Top