当const值传递给对象的构造函数时,它们应该通过引用还是值传递?
所有构造函数和初始化程序的教科书示例都按值传递,但这对我来说似乎效率低下。
如果您传递值并且参数立即用于初始化成员变量,那么是否会生成两个副本?这是编译器会自动处理的东西吗?
class Point {
public:
int x;
int y;
Point(const int _x, const int _y) : x(_x), y(_y) {}
};
int main() {
const int a = 1, b = 2;
Point p(a,b);
Point q(3,5);
cout << p.x << "," << p.y << endl;
cout << q.x << "," << q.y << endl;
}
VS
class Point {
public:
int x;
int y;
Point(const int& _x, const int& _y) : x(_x), y(_y) {}
};
编译并执行相同的操作,但这是正确的吗?
答案 0 :(得分:2)
对于简单类型传递值很好,您只需复制几个字节的数据。但是对于像矢量和字符串这样的更复杂的类型,最好传递一个const引用。如果您不需要它的副本,复制大字符串或向量是一种浪费。
答案 1 :(得分:1)
您在选择传递引用和传递值之间进行选择。请注意,这些功能签名是相同的。
Point( int x, int y );
Point( const int x, const int y );
从调用者的角度来看,参数是否被修改并不重要,因为当参数按值传递时总是进行复制。
如果要在构造函数外部初始化指向该实际对象的引用或指针,则需要传递引用,如果只需要其值,则通常优先传递值,除非复制对象的成本太高。对于int
,情况绝非如此。
答案 2 :(得分:1)
最好通过值而不是引用传递像int
这样的小原始类型。如果我没记错的话,引用在幕后实现为隐藏指针(即传入地址并自动取消引用它)。这意味着您仍然会产生复制和取消引用指针的开销(在某些体系结构上与int
的大小相同)。
通过引用传递给const
对于更大的用户定义类型肯定更有意义,因为它可以为您节省可能昂贵的复制操作。
答案 3 :(得分:0)
像int一样简单的东西应该通过值传递。
如果你有一个大的对象,那么通过引用传递是有意义的,因为它避免了不必要的副本。
请注意,如果您的对象是可变的,则传递引用或副本之间存在语义差异 - 在前一种情况下,您将看到对原始对象的更改,而在后一种情况下,您将不会。即使您已将其声明为const的引用,也是如此。