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;

}
4

3 回答 3

6

这正是你已经说过的。如果您不使用初始化列表,则将首先调用默认构造函数,然后调用赋值运算符。

在您的示例中,这是相对良性的(我认为编译器甚至可能对此进行优化)。但在其他情况下,根本不可能避免初始化列表。想象一下,如果X没有公共赋值运算符。

于 2011-09-10T20:47:59.040 回答
5

如果您使用Assignment,则:
x将首先默认构造,
然后使用obj.

成本是,默认构造+分配


如果您使用Member 初始化器列表,则:
x将被构造并初始化为obj.

成本是,仅建设

于 2011-09-10T20:48:28.990 回答
2
T(X &obj) : x(obj) {}

将从 obj 复制构造 x,而

T(X &obj){ x = obj; }

将构造一个默认 x,然后将其替换为来自 obj 的值。

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

于 2011-09-10T20:47:39.770 回答