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

发布于 2024-12-11 18:59:38 字数 466 浏览 0 评论 0原文

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

#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++ 倾向于在最意想不到的时候表现出未定义的行为,而且所有的人都说这是不可能的,我认为我错过了一些陷阱。我错过了什么吗?

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. Did I miss anything?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

吃素的狼 2024-12-18 18:59:38

它在语法上是正确的。但是,如果新的展示位置抛出异常,您
最终得到一个你无法破坏的物体。更不用说灾难了
如果有人来自你的班级。只是不要这样做。

解决方案很简单:如果类需要支持作业,则不要
使用任何参考成员。我有很多课程可供参考
参数,但将它们存储为指针,以便类可以支持
任务。像这样的东西:

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

It's syntactically correct. If the placement new throws, however, you
end up with an object you can't destruct. 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 ) {}
    // ...
};
小伙你站住 2024-12-18 18:59:38

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

};

Another solution is to use the reference_wrapper class ( in functional header ) :

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_;

};
农村范ル 2024-12-18 18:59:38

据我所知,你所做的在技术上是正确的,但它会产生麻烦。例如,考虑一下来自 A 的派生类会发生什么,因为它的赋值运算符会生成一个新对象(切片)。您不能将引用转换为类中的指针吗?

除此之外,复制构造函数和赋值运算符通常通过 const& 获取其参数。

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). 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&.

可是我不能没有你 2024-12-18 18:59:38

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

您应该使用复制和交换惯用语< /强>。与您的实施相比,它至少具有 3 个优势。

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. It has atleast 3 advantages over your implementation.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文