C ++: reasons for passing objects by value

In Java, all variables containing the correct objects are actually references (i.e. pointers). Therefore, method calls with these objects as arguments are always "by reference". Calling a method that changes the state of an object also affects the original object (from the subscriber).

C ++ is different: here arguments can be passed by value or passed by reference. Calling the mutator method on an object that was passed by value does not affect the original object. (I believe that calling by value creates a local copy of the object).

So, my first answer to this question - from Java to C ++ - is: ALWAYS use pointers when using objects as arguments. This gives me the behavior that I expected from Java.

However, you can also use "call by value" in case you do not need to change the object in the body of the method. Are there any reasons why you would like to do this?

+3
source share
8 answers

ALWAYS use pointers when using objects as arguments

No, in C ++ it is always passed by reference, unless your function can be called with nullptr as a valid argument. If the function does not need to change the argument, follow the link const .

Passing arguments by value has several uses.

If your function needs to create a copy of the argument, it is better to create this copy by going by value rather than creating a copy inside this function. For instance:

 void foo( widget const& w ) { widget temp( w ); // do something with temp } 

Use instead

 void foo( widget w ) // copy is made here { // operate on w itself } 

Doing this also has the advantage of letting the compiler move widget , if possible, which is usually more efficient than making copies.

+11
source

You are mistaken in that you need to follow the pointer. If you want to follow the link, well ... just follow the link:

 void foo(int& x) { x = 3; } int main() { int a = 0; foo(a); assert( a == 3 ); } 

Also note that passing by value ensures that your variable cannot be changed inside the called context. Although this will be passed by const reference ...

+9
source

If you pass objects to a function by value, this function can use these objects as “working” variables without affecting the caller.

+3
source

You usually pass a value because something is a value and should act as a value. In many cases, moving from a const reference is pretty close to what is worth considering. In other cases, this is not so.

Passing by value can also be an optimization . At least IMO, this is more or less secondary, but it can be important in any case (especially when choosing between passing by constant link and passing real value.

IMO, the real question should be in the opposite direction: why would the compiler pass the link when you clearly told it to pass the value? The answer is "premature optimization." The Java designers (to mention your example, although it is hardly unique in this) decided that they knew better than letting the compiler do what was said. Since moving a large object in value may be slow and may be a mistake, they decided not to allow it at all, although it could be quick and it could very well be exactly what was intended.

+3
source

in Java, a link is a "smart pointer" collected by garbage.

C ++ also uses the concept of smart pointers, which are in the <memory> library called unique_ptr and shared_ptr . shared_ptr is reference counting, so it can be used in the same way as Java references. unique_ptr is similar, except that it is not copyable and a bit lighter. The advantage of both will never be to use the delete keyword and be able to rely on “pointers” that are protected by exceptions.

C ++ also supports the concept of reference, which is usually a good choice for passing objects around (and even better, reference-to- const ). Links in C ++ are tied to the type of object being passed, so you need to specify (using the & symbol) in the function signature

 #include <string> void foo(std::string& bar) { bar = "world"; } void foo2(const std::string& bar) { //passed by reference, but not modifyable. } int main() { std::string str = "hello"; foo(str); foo2(str); } 

As for raw pointers, you can almost always avoid them using either a smart pointer, a link, an iterator, or a missing parameter. simple regular pointers come with a mixed-up "gotchas" package that C ++ inherited from C - if you have a fairly recent compiler, you never have to really use them at all (unless you are going to do things like reinvent the wheel for learning with memory management, data structures, etc.)

+2
source

I think you should consider the types of variables in your function signature as a contract with the caller. Therefore, if you declare that you function as:

 void foo( int a ); 

then you say that I will copy the passed value, do whatever I like and it will not be changed.

If you declare that:

 void foo (int* a); 

then I can change what a points or really modifies the pointer

so the semantic difference is that you declare what your function contract can do with pointers and links (without the constant declared in the link or the object that the pointer points to), you can change this variable.

In C ++, links are preferable, since it is clearer what you intend and avoid the style pointer with the signature functions of the pointer, which are necessary when passing pointers to functions where you want to change what the pointer points to, which leads to errors and headaches scratch before you understand what went wrong.

Pointers, although still very useful as parameters, especially if you need to check if a pointer to an object is null or not, is something that cannot be done using references.

+1
source

When passing by reference, there is an inherited danger that you may inadvertently change the value passed to the method inside the method. After calling the method, you can assume that the method did not change the object when it really did.

Passing by value has a negative aspect of the extra memory required (and possibly a little overhead), since you are making a copy of the object you are passing, but with the advantage that you can be sure that your object is not passed to the method inside method.

+1
source

Side effects are recommended. If you program this side effect, use the link call.

0
source

Source: https://habr.com/ru/post/1498101/


All Articles