📜  C++ 中的默认赋值运算符和引用

📅  最后修改于: 2022-05-13 01:54:59.834000             🧑  作者: Mango

C++ 中的默认赋值运算符和引用

我们在这里讨论了动态分配资源的赋值运算符重载。在本文中,我们讨论了当我们不编写自己的赋值运算符时,编译器会自己创建一个赋值运算符来进行浅拷贝,从而导致问题。当类有指针作为成员字段时,浅拷贝和深拷贝之间的区别变得明显。但是,不使用指针时没有区别。当我们的类中有引用并且没有用户定义的赋值运算符时会发生什么。

例如,预测以下程序的输出,

CPP
// CPP program to demonstrate  references in a class and
// there is no user defined assignment operator
#include 
using namespace std;
  
class Test {
    int x;
    int& ref;
  
public:
    Test(int i)
        : x(i)
        , ref(x)
    {
    }
    void print() { cout << ref; }
    void setX(int i) { x = i; }
};
  
// Driver Code
int main()
{
    Test t1(10);
    Test t2(20);
    t2 = t1;
    t1.setX(40);
    t2.print();
    return 0;
}


CPP
// CPP Program to demonstrate assignment operator
#include 
using namespace std;
  
class Test {
    int x;
    int& ref;
  
public:
    Test(int i)
        : x(i)
        , ref(x)
    {
    }
    void print() { cout << ref; }
    void setX(int i) { x = i; }
    Test& operator=(const Test& t)
    {
        x = t.x;
        return *this;
    }
};
  
int main()
{
    Test t1(10);
    Test t2(20);
    t2 = t1;
    t1.setX(40);
    t2.print();
    return 0;
}


输出:

Compiler Error: non-static reference member 'int& Test::ref', 
             can't use default assignment operator

在以下情况下,编译器不会创建默认赋值运算符:

1.类具有const类型或引用类型的非静态数据成员
2.类有一个类型的非静态数据成员,该类型具有不可访问的复制赋值运算符。
3.类派生自具有不可访问的复制赋值运算符的基类。

当上述任一条件为真时,用户必须定义赋值运算符。例如,如果我们在上面的代码中添加一个赋值运算符,代码可以正常工作,没有任何错误。

CPP

// CPP Program to demonstrate assignment operator
#include 
using namespace std;
  
class Test {
    int x;
    int& ref;
  
public:
    Test(int i)
        : x(i)
        , ref(x)
    {
    }
    void print() { cout << ref; }
    void setX(int i) { x = i; }
    Test& operator=(const Test& t)
    {
        x = t.x;
        return *this;
    }
};
  
int main()
{
    Test t1(10);
    Test t2(20);
    t2 = t1;
    t1.setX(40);
    t2.print();
    return 0;
}
输出
10