Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 具有引用成员的赋值运算符_C++_Reference - Fatal编程技术网

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

C++ 具有引用成员的赋值运算符,c++,reference,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)

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

#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;
    }
}
#包括
结构A
{
int&ref;
A(int&Ref):Ref(Ref){}
A(常数A&second):ref(second.ref){}
运算符=(常量A和秒)
{
如果(此==&秒)
归还*这个;
这个->~A();
新(本)A(第二);
归还*这个;
}
}

< >似乎编译得很好,但是C++在没有预料到的情况下倾向于不确定的行为,所有那些说不可能的人,我想我错过了一些机会。我错过了什么吗?

据我所知,你所做的技术上是正确的,但会带来麻烦。例如,考虑派生类从<代码> A<代码>中发生的情况,因为它的赋值操作符生成新对象(切片)。你不能在你的类中将引用变成指针吗


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

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


您应该使用实现它。与您的实现相比,它至少有3个优点。

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

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

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

另一种解决方案是使用reference_包装类(在函数头中):

结构A { A(int&A):A_uz(A){} A(常数A&A):A(A.A){ A&A运算符=(常量A&A) { a=a.a; 归还*这个; } void公司()常数 { ++a); } 标准::参考包装; };
顺便说一下,
运算符=
和复制构造函数的参数应该是常量引用。正确性可能仅限于标准布局类型,由于使用virtuals
时,此
不必是指向内存块开头的指针。如果需要这样做,我建议重新考虑使用引用。引用无法重置。如果你需要重新安装一个,那么引用一开始就不是正确的类型。这怎么会产生问题呢?但是如何交换引用呢?@ChristianRau:无论如何,你将实现自己的
交换
函数。是的,这可能需要交换引用。具体来说,
swap
需要销毁
A
,然后调用placement new,就像这样。复制和交换取决于是否有可用的nothrow交换实现,而这种类型没有。@DennisZickefoose:它可以为您节省自分配检查。我喜欢这样——简单明了的解决方案!使用赋值表达式
a=b
a
具有类型
reference\u wrapper
时,似乎如果
b
具有类型(可转换为?
reference\u wrapper
),这将重置
a
以引用
b
,但如果没有,并且
b
具有类型(可转换为?
T
a
引用的
T
对象将被分配值
b
。这是真的吗?如果是这样的话,它似乎为实现执行
a=b的函数模板引入了一些微妙之处b
的类型可以隐式转换为
a
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_;

};