构造函数中的初始化列表

5
我听说使用构造函数中的初始化列表的优点在于不会有额外的类类型对象拷贝。但是对于类 T 构造函数中的以下代码来说,这意味着什么?如果我注释掉赋值并使用初始化列表,会有什么区别吗?
#include <iostream>
using std::cout;
using std::endl;
using std::ostream;

class X {

public:

    X(float f_x = 0, float f_y = 0):x(f_x), y(f_y) {}


    ~X() {}

    X(const X& obj):x(obj.x), y(obj.y) {}

    friend ostream& operator << (ostream &os, X &obj);

private:
    float x;
    float y;
};

ostream& operator << (ostream &os, X &obj)
{ os << "x = " << obj.x << " y = " << obj.y; return os;}

class T {

public:

    T(X &obj) : x(obj) { /* x = obj */ }

    ~T() { }

    friend ostream& operator << (ostream &os, T &obj);

private:

    X x;

};

ostream& operator << (ostream &os, T &obj)
{ os << obj.x; return os; }

int main()
{
    X temp_x(4.6f, 6.5f);

    T t(temp_x);

    cout << t << endl;

}

不确定是否与您的问题相关,但您可能需要 T( X const& obj )。 - K-ballo
@K-ballo:是的,我忘记了,谢谢。 - user767451
3个回答

6

就像你已经说的一样。如果不使用初始化列表,那么默认构造函数将首先被调用,然后调用赋值运算符。

在你的示例中,这相对较为温和(我认为编译器甚至可能会优化这个过程)。但在其他情况下,无法避免使用初始化列表。想象一下如果X没有公共的赋值运算符会怎样。


啊,我错过了重载赋值运算符函数,没有注意到它在我的代码中的影响。我把它和复制构造函数混淆了! - user767451

5
如果您使用赋值,那么:
x 将首先进行默认构造 &
然后使用obj进行赋值。
成本是默认构造 + 赋值
如果您使用成员初始化列表,那么:
x 将被构造并使用obj进行初始化。
成本仅为 构造

2
T(X &obj) : x(obj) {}

将从obj复制构造x,而
T(X &obj){ x = obj; }

将会构建一个默认的x,然后用obj中的值替换它。

如果您打算构建一个成员对象,应该在初始化列表中进行。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接