具有参考成员的分配操作员

时间:2011-10-26 16:57:22

标签: c++ reference

这是创建具有引用成员的赋值运算符的有效方法吗?

#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 ++倾向于在最不期望的时候表现出未定义的行为,并且所有说不可能的人,我认为我错过了一些问题。我错过了什么吗?

4 个答案:

答案 0 :(得分:35)

它在语法上是正确的。但是,如果放置新的投掷,你 最终得到一个你无法破坏的对象。更不用说灾难了 如果有人来自你的班级。只是不要这样做。

解决方案很简单:如果类需要支持赋值,请不要 使用任何参考成员。我有很多课程需要参考 参数,但将它们存储为指针,这样类就可以支持 分配。类似的东西:

struct A
{
    int* myRef;
    A( int& ref ) : myRef( &ref ) {}
    // ...
};

答案 1 :(得分:6)

另一个解决方案是使用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_;

};

答案 2 :(得分:4)

据我所知,你在技术上做了什么,但它会带来麻烦。例如,考虑来自A的派生类会发生什么,因为它的赋值运算符生成一个新对象(切片)。你不能把引用变成你班级中的指针吗?

除此之外,复制构造函数和赋值运算符通常采用const&

的参数

答案 3 :(得分:1)

您所做的是正确的,但编写复制赋值运算符并非异常安全。此外,您应该考虑使用指针成员而不是引用成员。

您应该使用 Copy and Swap Idiom 来实现它。它比您的实现具有至少3个优势。