繁体   English   中英

具有引用成员的赋值运算符

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM