Far*_*hid 5 c++ pass-by-reference pass-by-value
我正在阅读 Scott meyers 的《Effective C++》,作者正在比较按值传递和按引用传递。对于用户定义的类型,建议使用按引用传递,对于内置类型,建议使用按值传递。我正在寻找一个示例来解释以下段落,该段落指出即使对于小型用户定义对象,按值传递的成本也可能很高。
\n\n\n\n内置类型很小,因此有些人得出结论,所有小类型\n都是值传递的良好候选者,即使它们\xe2\x80\x99是用户定义的。\n这是不稳定的推理。仅仅因为一个对象很小,\xe2\x80\x99并不意味着\n调用它的复制构造函数是廉价的。许多对象 \xe2\x80\x94 其中大多数\n STL 容器 \xe2\x80\x94 只包含一个指针,但是\n 复制这些对象需要复制它们指向的所有内容。这可能会非常昂贵。
\n
这取决于你的副本是深复制还是浅复制。(或者类似值的类/类似指针的类)。例如,A是一个只有一个指向另一个对象的指针的类:
\n\nstruct B;\nstruct A\n{\n B* pB;\n ~A{delete pB;}\n}a1,a2;\nRun Code Online (Sandbox Code Playgroud)\n\n如果你A按值复制,比如a1=a2,将调用默认的按位复制赋值,这是很小的成本,但是,通过这样做,你会让 in pB,a1指向a2相同的堆内存。也就是说,dtor~A()可能是调用两次,这是未定义的行为。
所以我们必须这样做:
\n\n struct A\n { \n B* pB;\n const A& operator=(const A&rhs)\n {\n if(this!=&rhs)\n {\n delete pB;\n pB=new pB;\n *pB=*rhs.pB;\n }\n return *this;\n }\n //the copy/move constructor/assignment should also be redefined\n ~A{delete pB;}\n }a1,a2\nRun Code Online (Sandbox Code Playgroud)\n\n上面的代码片段将调用 的复制分配B,这可能会非常昂贵。
总而言之,如果您的类是可简单复制的,那么复制一个小的用户定义类或按值传递不会花费太多\xef\xbc\x8celse,这取决于情况。
\n\n如果你仍然想按值传递并且不想触发未定义的行为,shared_ptr可能是你的一个不错的选择。但是正如@Arne Vogel指出的,shared_ptr的实现是线程安全的,这需要对引用进行原子操作算起来会增加成本。
\n