常量构造函数是否应通过引用或值传递?

时间:2011-01-07 23:44:49

标签: c++ constructor pass-by-reference

当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) {}
};

编译并执行相同的操作,但这是正确的吗?

4 个答案:

答案 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的引用,也是如此。