关于类中c++引用的混淆

confusion about c++ reference in class

本文关键字:引用 于类中 c++      更新时间:2023-10-16

以下代码是正确的

    string s1="abc";
    string s2="bcd";
    string &rs1=s1;
    string &rs2=s2;
    rs1=rs2;
    cout<<rs1<<"----"<<rs2<<endl;

以下代码将编译错误:

class A
{
public:
    A(string& a):ma(a) { }
    string& ma;
};
string s1="abc";
string s2="bcd";
A oa(s1);
A ob(s2);
oa=ob;
cout<<oa.ma<<"----"<<ob.ma<<endl;

以上都是string&类型赋值,为什么把它们放到类中会导致编译错误?(gcc版本4.7.1)

错误信息为

non-static reference member 'std::string& A::ma', can't use default assignment operator

您正在设置对本地临时变量的成员引用。构造函数中的参数是一个temp)。这导致了"悬空引用",这是不好的。

将参数更改为引用,或将成员更改为非引用。出于您的目的,您可能想要:

class A
{
public:
    A(string& a):ma(a) { }
    A& operator =(const A& other) 
    { 
        ma = other.ma; 
        return *this; 
    }
    string& ma;
};

但你应该知道,你的类的默认复制构造函数可能不会做你认为会做的事情。

更新

当类具有引用成员时,处理为什么删除默认副本分配运算符的标准的特定区域:

C++11§12.8,p23

如果X具有以下情况,则类X的默认复制/移动分配运算符定义为已删除:-具有非平凡对应赋值运算符的变体成员,X是类并集,或

  • const非类类型的非静态数据成员(或其数组),或
  • 引用类型的非静态数据成员,或
  • 类类型为M的非静态数据成员(或其数组),由于应用于M的相应赋值运算符的重载解析(13.3)导致模糊性或从默认赋值运算符中删除或无法访问的函数,因此无法复制/移动,或
  • 无法复制/移动的直接或虚拟基类B,因为应用于B的相应赋值运算符的重载解析(13.3)导致模糊性或从默认赋值运算符中删除或无法访问的函数,或者
  • 对于移动赋值运算符,非静态数据成员或类型不具有移动赋值运算符且不可复制的直接基类,或任何直接或间接虚拟基类