简体   繁体   English

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

[英]Assignment operator with reference members

Is this a valid way to create an assignment operator with members that are references?这是创建具有引用成员的赋值运算符的有效方法吗?

#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;
    }
}

It seems to compile and run fine, but with c++ tendency to surface undefined behavior when least expected, and all the people that say its impossible, I think there is some gotcha I missed.它似乎编译和运行良好,但是 C++ 倾向于在最不期望的情况下显示未定义的行为,并且所有的人都说这是不可能的,我认为我错过了一些问题。 Did I miss anything?我错过了什么吗?

It's syntactically correct.它在语法上是正确的。 If the placement new throws, however, you end up with an object you can't destruct.但是,如果放置 new 抛出,您最终会得到一个无法破坏的对象。 Not to mention the disaster if someone derives from your class.如果有人从您的班级派生,则更不用说灾难了。 Just don't do it.只是不要这样做。

The solution is simple: if the class needs to support assignment, don't use any reference members.解决方法很简单:如果类需要支持赋值,不要使用任何引用成员。 I have a lot of classes which take reference arguments, but store them as pointers, just so the class can support assignment.我有很多类接受引用参数,但将它们存储为指针,以便该类可以支持赋值。 Something like:就像是:

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

Another solution is to use the reference_wrapper class ( in functional header ) :另一种解决方案是使用 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_;

};

What you do its technically correct as far as I know, but it generates trouble.据我所知,你所做的在技术上是正确的,但它会产生麻烦。 For instance, consider what happens with a derived class from A , since its assignment operator generates a new object (slicing).例如,考虑从A派生的类会发生什么,因为它的赋值运算符生成一个新对象(切片)。 Can't you just turn the reference into a pointer within your class?您不能将引用转换为类中的指针吗?

Besides that, copy constructors and assignment operators usually take its argument by const& .除此之外,复制构造函数和赋值运算符通常通过const&获取其参数。

What you do is correct, but it is not very exception safe way of writing an copy assignment operator.您所做的是正确的,但它不是编写复制赋值运算符的非常安全的方法。 Also, You should consider using a pointer member rather than an reference member.此外,您应该考虑使用指针成员而不是引用成员。

You should implement it using the Copy and Swap Idiom .您应该使用Copy and Swap Idiom来实现它。 It has atleast 3 advantages over your implementation.与您的实施相比,它至少有 3 个优势。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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