【发布时间】:2015-12-17 06:31:42
【问题描述】:
所以考虑下面的代码:
#include <iostream>
using namespace std;
class A {
public:
A() = default;
A(const A& rhs) {
cout << "Copy was made!" << endl;
}
};
class B {
public:
A data;
int foo;
B(A data, int foo) : data(data), foo(foo) {
}
};
int main() {
A data;
B foo(data, 10);
return 0;
}
打印出来:
已复制!
已复制!
是的,没错,它会复制两次!
当我们将data 传递给B's 构造函数时,会发生第一个副本。
第二次复制发生在我们将data 从构造函数复制到成员变量时。
我们知道我们不能低于 1 个副本(除非我们去 heap & pointers)。那么我们为什么不总是写:
B (const A& data, const int& foo, const SomeOtherType& bar, const float& aFloatyNumber) ...等等。
我知道按值传递 int、float 等很便宜。但是通过始终将const ref 用作Constructor 参数,我们将保证减少1 个副本。
【问题讨论】:
-
we will garantie 1 less copy这仅在副本昂贵时才重要。复制int很便宜 - 比通过引用访问同一int所需的间接成本更低。 -
并且没有人阻止您改用
const A& data。对于 POD,它没有任何区别,可能编译器优化了间接并简单地复制了int等。 -
因为您正在寻找的语义是移动语义(右值引用附带)而不是副本。
-
c++ 中的所有内容都是通过值“在引擎盖下”传递的,这是从 c 继承而来的。由于引用可以并且通常使用指针实现,因此您仍然必须为每个函数调用复制底层指针。这将比复制一个 int 更昂贵,因为你最终会得到一个间接的结果。
-
我们总是将 const ref 用于非平凡的类型。除非我们使用 move 语义。不仅适用于构造函数。除非你特别想要一份副本。
标签: c++ c++11 constructor pass-by-reference pass-by-value