关于复制构造

时间:2015-01-30 07:47:48

标签: c++ copy-constructor default-copy-constructor

class Wood {
public:
    Wood();
    Wood(const Wood&); //copy constructor
    ~Wood();

private:
    string price;
};

Wood::Wood(const Wood& orig) {
    price(orig.price);   **//error, why?**
}

Wood::Wood(const Wood& orig) : price(orig.price) { //rigth

}

如果我使用构造初始化并且它是正确的。但如果使用"价格(orig.price)"它会出错,为什么?

3 个答案:

答案 0 :(得分:4)

构造函数的函数体(开括号和闭括号之间的部分)与任何其他函数的主体没有区别。你期望这个编译:

std::string a, b;
a(b);  // <--- this line?

不,当然不是。为了编译它,std::string需要类似operator()重载的东西,它需要另一个字符串。它没有那个。

初始化列表中的代码不同。初始化列表中的表达式不会被解释为正常语句,就像函数体内的语句一样。它们被解释为初始化(例如构造函数调用)。因此,在初始化列表中,这个:

: price(orig.price)

等同于这样的陈述:

std::string price(orig.price);

除了不需要指定price的类型之外,因为那已经在类定义中完成了。

请注意,您无法在构造函数体内进行成员初始化,因为到达那里时,所有成员都已初始化。这就是你需要初始化列表的原因。当然,您可以在构造函数体中进行赋值:

price = orig.price;

但这与初始化不同。它不适用于某些类型(例如const成员,引用成员或没有默认构造函数的成员)。对于某些类型,它可能效率较低,因为您首先构建(使用默认构造函数),然后分配。但对于许多类型而言,它并不重要,因为默认构造几乎没有任何成本。

答案 1 :(得分:1)

这是不正确的,因为价格已经构建完毕。如果已经构建了复制构造函数,则无法调用它。

你必须做一些像price = orig.price;

答案 2 :(得分:1)

检查编译错误,您将看到原因。在成员初始值设定项列表中,price(orig.price)是成员变量price的{​​{3}},其值为orig.price。在复制构造函数的主体中,price(orig.price)是对operator()中重载std::string的调用,该std::string接受{{1}}。由于没有这样的重载,因此会出现编译错误。