背景 我有一个复杂的类,有很多变量。我有一个声音和测试的复制构造函数:
Applepie::Applepie( const Applepie ©) :
m_crust(copy.m_crust),
m_filling(copy.m_filling)
{
}
在inativeizer列表中调用的一些成员变量复制构造函数执行分配。
问题:
我需要创建operator=
。我可以简单地执行以下操作,而不是使用赋值而不是初始化列表复制现有的构造函数,释放正在被替换的内存等等,我可以简单地执行以下操作:
Applepie& Applepie::operator=( const Applepie ©)
{
if( this != ©)
{
this->~Applepie(); // release own object
new(this) Applepie(copy); // placement new copy constructor
}
return *this;
}
换句话说,是destroy self后跟一个放置新的复制构造函数在语义上与operator =?
相同这似乎有可能大大减少重复代码并确认每个变量都已正确初始化,但代价是在分配期间可能会略微降低效率。我错过了一些比较模糊的东西吗?
理由: 我的实际班级有大约30个变量。我担心我的复制构造函数和我的赋值操作符都必须复制所有三十个,并且代码可能会发散,导致两个操作以不同的方式执行操作。
答案 0 :(得分:6)
正如“Exceptional C ++”中的Herb Sutter所说,它并非例外。这意味着,如果在new
或构造新对象期间出现任何问题,则赋值的左手操作数处于错误(未定义)状态,从而需要更多麻烦。我强烈建议您使用copy & swap idiom。
Applepie& Applepie::operator=(Applepie copy)
{
swap(m_crust, copy.m_crust);
swap(m_filling, copy.m_filling);
return *this;
}
当你的对象也使用 Pimpl idiom (指向实现的指针)时,只需更改两个指针即可完成交换。
答案 1 :(得分:1)
除了Rene的回答之外,如果ApplePie是实际对象的基类,还会出现问题:ApplePie会用错误类型的对象替换对象!