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)"它会出错,为什么?
答案 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}}。由于没有这样的重载,因此会出现编译错误。