C++: Reasons for passing objects by value

2019-02-15 06:46发布

In Java, all variables containing proper objects are actually references (i.e. pointers). Therefore, method calls with these objects as arguments are always "by reference". Calling a method which modifies the state of the object also affects the original object (on the caller side).

C++ is different: Here arguments can be passed by value or passed by reference. Calling a mutator method on an object which was passed by value leaves the original object unaffected. (I suppose call by value creates a local copy of the object).

So my first response to this - coming from Java to C++ - is: ALWAYS use pointers when using objects as arguments. This gives me the behavior I have come to expect from Java.

However, one could also use "call by value" in case one does not need to modify the object in the method body. Are there reasons why one would want to do this?

标签: java c++ oop
8条回答
Emotional °昔
2楼-- · 2019-02-15 07:08

You normally pass by value because something is a value and should act like a value. In many cases passing by const reference is close enough to the same to be worth considering. In other cases, it's not.

Passing by value can also be an optimization. At least IMO, this more or less secondary, but it can be important anyway (especially in choosing between passing by const reference and passing a real value.

IMO, the real question should be in the opposite direction: why should the compiler pass a reference when you've clearly told it to pass a value? The answer is "premature optimization". The designers of Java (to mention your example, though it's hardly unique in this) decided that they knew better than to let the compiler do what it was told. Since passing a large object by value can be slow and might be a mistake, they decided to not let it happen at all, even though it can be fast and may well be exactly what was intended.

查看更多
可以哭但决不认输i
3楼-- · 2019-02-15 07:19

in Java, a reference is a garbage-collected "smart pointer".

C++ also uses the concept of smart pointers, which are in the <memory> library, called unique_ptr and shared_ptr. shared_ptr is reference-counted so can be used in the same way as Java References. unique_ptr is similar, except is noncopyable and a little more lightweight. The benefit of both is never ever needing to use the delete keyword, and being able to rely on "pointers" which are protected by exceptions.

C++ also supports the concept of a reference - which is usually a good choice for passing objects around (And even better is reference-to-const). References in C++ are bound to the type of object which is passed, so you need to specify (using the reference 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 nearly always avoid them by using either a smart pointer, a reference, an iterator, or pass-by-value. plain ordinary pointers come with a mixed bag of "gotchas" which C++ inherited from the C language - if you've got a fairly recent compiler you should never really need to use them at all (unless you're going to be doing things like re-inventing the wheel for learning purposes with memory management, data structures, etc.)

查看更多
The star\"
4楼-- · 2019-02-15 07:22

It's helpfull to avoid side-effects. If you program need such side-effect use call by reference.

查看更多
混吃等死
5楼-- · 2019-02-15 07:25

You're wrong in that you should pass by pointer. If you want to pass by reference, well... simply pass by reference:

void foo(int& x)
{
   x = 3;
}

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

Also, note that passing by value guarantees that the your variable can't be changed inside the called context. Although so would passing by const reference...

查看更多
戒情不戒烟
6楼-- · 2019-02-15 07:25

When passing by reference there is an inherit danger that you could inadvertently change the value passed to the method, inside the method. After the method call you could assume the method didn't change the object, when in fact it did.

Passing by value has the negative aspect of extra memory required (and possibly a slight performance overhead) because you make a copy of the object you are passing in, but with the benefit that you can be sure your object passed into the method will not be modified inside the method.

查看更多
女痞
7楼-- · 2019-02-15 07:27

If you pass objects to a function by value, that function is free to use those objects as "working" variables without affecting the caller.

查看更多
登录 后发表回答