通过引用的C++类成员

C++ class member by reference

本文关键字:成员 C++ 引用      更新时间:2023-10-16

你好,有人能帮我吗?我有一个参考成员的班级:

class name{
int& broj;
string ulica;

并具有构造函数:

public:
kuca(int b, string s) :broj(b)
{
    ulica = s;
}

和输出的信息类

void info(){
cout << broj << ulica << endl;
}
};

当我创建对象并尝试将其输出时

int isbn = 1;
name a(isbn, "text");
a.info();

对于参考值,我得到的是垃圾/随机值,而其他属性写得很好:

 -858993460 text

引用成员总是有悬空的危险:当引用引用的原始对象超出范围时。在您的情况下,这种情况会立即发生(因为对象是临时的),但即使您遵循的建议

kuca(int&b, const string&s) : broj(b), ulica(s) {}
     ^^^^^

你很容易惹上麻烦。例如

kuca make_kuca()
{
  int x=7;
  return {x,"bad"};
}
auto k=make_kuca();

当返回对象的引用成员引用刚刚超出范围的变量(x)时。

因此,应该谨慎使用引用数据成员,以确保它们的生存期永远不会超过它们引用的变量的生存期。

您必须至少编写

kuca( int &b, string s) :broj(b)
      ^^^^^^
{
    ulica = s;
}

否则,变量b是构造函数的局部变量/对象,在执行构造函数后将被销毁,引用将无效。

按如下方式更改ctor签名:

kuca(int& b, string s) :broj(b)

注意CCD_ 2而不是CCD_。然后,参数b将引用变量isbn,而不是某个调用堆栈位置。

需要注意的是,使用原始签名

kuca(int b, string s) : broj(b)

您正在获取参数的引用,该参数是在堆栈上传递的副本。因此,当调用info()方法时,broj引用调用堆栈上的一个位置,而不是变量isbn。这就是为什么它似乎打印一个"随机"值。

您正在存储对参数b的引用,该参数仅在构造函数调用期间存在。在构造函数调用之后,您只能引用一个不存在的int

正如大家已经说过的,你可能是这个意思。。。

kuca(int b, string s) :broj(b)

成为

kuca(int& b, string s) :broj(b)

不过,通过引用传递int对性能没有任何好处,而且一旦int超出范围,引用就会无效,这可能会造成难以追踪的错误。

我个人的偏好是,只要变量可以发生变异,就通过地址传递。

class name {
  public:
    kuca(int* b, string s) : broj(b), ulica(s);
  private:
    int* broj;
    string ulica;
}

这将把上面的内容变成编译时错误。使用引用作为类成员很容易被错误地使用。