3

这是一个古老的考试问题,它要求我们编写赋值运算符和复制构造函数,在有意义的情况下编写析构函数。

给定以下代码:

class U { /* code not specified here */ };
class A { /* code not specified here */ private: U& u_; };

我了解到答案是:A 持有对 U 实例的 C++ 引用,可以复制但不能重置。因此,您必须:

• 编写一个复制构造函数,将其 U 初始化为 A 源实例引用的同一实例。

• 将其赋值运算符设为私有且不实现

我知道引用无法重置。但是,这是否意味着当类包含引用成员数据时,我永远不能使用赋值运算符?下面的代码有意义吗?以下代码是我自己写的(不是答案)

  class U{
    public:
        int u;
    };

    class A{
    public:
        A(U& u):u_(u){}
        A& operator=(const A& a){
            u_ = a.u_;
            return *this;
        }
        U& u_;
    };

    int main(){
        U u1;
        U u2;
        A a1(u1);
        A a2(u2);
        a1 = a2;
        a1.u_.u = 1;
        a2.u_.u = 2;
        cout << "a1.u_.u : " << a1.u_.u << endl;
        cout << "a2.u_.u : " <<  a2.u_.u << endl;
    }

提前致谢。

4

5 回答 5

2
A& operator=(const A& a){
    u_ = a.u_;
    return *this;
}

无法按预期工作,U将分配参考点。
当然,即使类包含引用,您也可以实现赋值运算符,只要可以分配该引用(如果引用的类operator=只有 privat 怎么办?)并且引用不是const U&(因此无法分配)。

于 2011-03-06T00:58:08.223 回答
2

不能将引用更改为引用其他内容。但是,您可以在这里做您所做的事情,因为这样做:

u_ = a.u_;

实际上会更改引用的值。它确实注意到更改引用的值。

于 2011-03-06T01:00:06.523 回答
1

引用可以看作是指针。唯一的区别是,一旦分配参考,您就无法更改参考指向的位置。在您的赋值运算符中,您正在复制引用的内容,而不是分配引用指向的位置。

对于编译器,以下类是等效的,请注意指针版本取消引用指针以复制内容:

class A_Ref{
public:
    A_Ref(U& u):u_(u){}
    A_Ref& operator=(const A_Ref& a){
        u_ = a.u_;
        return *this;
    }
    U& u_;
};

class A_Ptr{
public:
    A_Ptr(U* u):u_(u){}
    A_Ptr& operator=(const A_Ptr& a){
        *u_ = *a.u_;
        return *this;
    }
    U* u_;
};
于 2011-03-06T01:13:35.920 回答
1

这是否意味着只要类包含引用成员数据,我就永远不能使用赋值运算符?

您可以有一个赋值运算符,但您不能重新分配引用,因此需要重新定义赋值运算符的预期行为。

于 2011-03-06T01:34:01.713 回答
0

您甚至不必将赋值运算符设为私有,因为如果存在 const 成员或引用,编译器将知道不会生成一个。这些不能重新分配。

于 2011-03-06T10:31:41.030 回答