Why would you ever take the copy of an object as a parameter to your function? Why are not const ref the default way of parameters?

纵然是瞬间 提交于 2021-02-07 23:27:57

问题


As much as I enjoy C++ programming, there is one thing I really don't get. To me, it seems that the most common way of programming a function is like this:

some_function(a variable)
    do something according to the data in the variable

example:

bool match_name(const std::string& name)
{
    return this->name == name;
}

I find myself using const ref for 90% of all function parameters in my code (maybe I'm doing something wrong).

My question is: Why is a copy of the variable the "default" type of parameters? Why are not const ref the default?

Why not something like?:

void my_function(My_type object)      // <- const ref

void my_function(ref My_type object)  // <- ref (mutable)

void my_function(copy My_type object) // <- copy

回答1:


C++ wants to be compatible with C, and since C uses value semantics by default, so does C++. It would be very inconsistent to take build-in types by value but other types by reference.

However, passing by reference is not always better. The pointer indirection a reference causes generally makes it harder for the compiler to optimize code gen. In many cases, passing a type by value is still better than by ref. It depends on the type. The pointer indirection of references might cause a memory read, while passing by value allows the object to be passed in CPU registers. For example, a type like this:

class Point {
public:
    /* functions */
private:
    int x;
    int y;
};

Should always be passed by value. It's just two integers. A reference might cause unneeded memory reads to get to the values.

Also, sometimes you want to pass by value even if the type cannot be enregistered. So called "sink functions" for example that need to store the passed value perform better with values due to move semantics. Prime examples are constructros and setters:

void SomeClass::setString(std::string s)
{
    this->s_ = std::move(s);
}

Passing by reference in this case can incur extra copies. You can read up more on this online. A good starting point is this SO question:

Are the days of passing const std::string & as a parameter over?




回答2:


Apart from historical reasons, that would have very ugly implications. It basically means that MyType myVarName would have different meaning when is scope of function or when used in function argument list.

void foo(MyType myVar) //myVar is const ref
{
    MyType anotherVar = myVar; // anotherVar is a copy, what?
    const MyType& myVarRef = myVar; //a reference, but it looks like it has different type than myVar?
}

And think of the poor &! Unless you propose a different way of distinguishing refs from non-refs, you end up with

void foo(MyType& myVar) //myVar is a copy?
{
    MyType& anotherVar = myVar; // anotherVar is a reference???
}

C++ has a well established notion of object and reference to object. The latter is always denoted by adding & to type. Your proposition would mess that up and C++ would be even harder to understand than it is.



来源:https://stackoverflow.com/questions/60522677/why-would-you-ever-take-the-copy-of-an-object-as-a-parameter-to-your-function-w

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!