[英]Assignment operator with reference members
这是创建具有引用成员的赋值运算符的有效方法吗?
#include <new>
struct A
{
int &ref;
A(int &Ref) : ref(Ref) { }
A(const A &second) : ref(second.ref) { }
A &operator =(const A &second)
{
if(this == &second)
return *this;
this->~A();
new(this) A(second);
return *this;
}
}
它似乎编译和运行良好,但是 C++ 倾向于在最不期望的情况下显示未定义的行为,并且所有的人都说这是不可能的,我认为我错过了一些问题。 我错过了什么吗?
它在语法上是正确的。 但是,如果放置 new 抛出,您最终会得到一个无法破坏的对象。 如果有人从您的班级派生,则更不用说灾难了。 只是不要这样做。
解决方法很简单:如果类需要支持赋值,不要使用任何引用成员。 我有很多类接受引用参数,但将它们存储为指针,以便该类可以支持赋值。 就像是:
struct A
{
int* myRef;
A( int& ref ) : myRef( &ref ) {}
// ...
};
另一种解决方案是使用 reference_wrapper 类(在功能标头中):
struct A
{
A(int& a) : a_(a) {}
A(const A& a) : a_(a.a_) {}
A& operator=(const A& a)
{
a_ = a.a_;
return *this;
}
void inc() const
{
++a_;
}
std::reference_wrapper<int>a_;
};
据我所知,你所做的在技术上是正确的,但它会产生麻烦。 例如,考虑从A
派生的类会发生什么,因为它的赋值运算符生成一个新对象(切片)。 您不能将引用转换为类中的指针吗?
除此之外,复制构造函数和赋值运算符通常通过const&
获取其参数。
您所做的是正确的,但它不是编写复制赋值运算符的非常安全的方法。 此外,您应该考虑使用指针成员而不是引用成员。
您应该使用Copy and Swap Idiom来实现它。 与您的实施相比,它至少有 3 个优势。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.