【问题标题】:Are const references to members safe对成员的 const 引用是否安全
【发布时间】:2015-11-02 00:52:48
【问题描述】:

如果我使用 const 引用另一个成员, 这个引用是否有可能失效?

class Class {
public:
    const int &x{y};
private:
    int y;
};

例如,当我在向量中使用此类的实例时 在push_back 之后增加了它的容量。 根据标准,所有迭代器和引用都无效,如果 向量必须增加其容量。之后引用仍然有效吗?

【问题讨论】:

  • 如果您可以将其推入向量并在您认为的位置设置x 点,我会感到惊讶。
  • 不应该对每个新插入的Class 实例进行回推吗?数据将被复制到向量中,其中 x 指向新的 y 位置。
  • 如果您在push_back() 之前获取了引用,它不会指向向量内的那个元素。 push_back() 复制一份。
  • 这实际上是关于被引用的值而不是引用本身的问题。

标签: c++ reference member getter invalidation


【解决方案1】:

目前这是不安全的,因为当您复制Class 的实例时,x 将引用复制对象的y,而不是它自己的y。您可以通过运行以下代码来看到这一点:

int main()
{
    Class a{};
    std::vector<Class> vec;
    vec.push_back(a);

    //these lines print the same address
    std::cout << &(a.x) << std::endl;
    std::cout << &(vec[0].x) << std::endl;
}

您可以通过编写自己的复制构造函数和赋值函数来正确初始化x 来解决此问题:

Class (const Class& rhs) : x{y}, y{rhs.y} {}

这是安全的,因为x 和y 只会与您的对象一起被销毁。 std::vector 的引用无效意味着对向量元素的引用:

Class c;
std::vector<Class> vec;
vec.push_back(c);

Class& cr = vec[0];
//other operations on vec
std::cout << c.x; //fine, that reference is internal to the class
std::cout << cr.x; //cr could have been invalidated

【讨论】:

  • 如果我覆盖复制 ctor 并且向量在推回后必须增长,它是否仍然有效?那么这些引用仍然有效吗?
  • 是的,这就是最后一段和sn-p地址。
【解决方案2】:

假设这是对来自同一实例的另一个成员的引用,您需要重写复制构造函数来初始化它。默认复制构造函数将从可能无效的旧实例中复制对“y”的引用。

为什么需要对成员的引用是另一个问题。

附:出于同样的原因,您还需要覆盖赋值运算符。

【讨论】:

  • 我认为它是普通 getter 的替代品。
猜你喜欢
  • 1970-01-01
  • 2016-07-11
  • 1970-01-01
  • 1970-01-01
  • 2021-02-05
相关资源
最近更新 更多