【问题标题】:Is there a way to be sure that a const reference stored in class will always refer to a valid object?有没有办法确保存储在类中的 const 引用总是引用一个有效的对象?
【发布时间】:2014-05-13 00:56:28
【问题描述】:

我编写了以下示例代码:

#include <iostream>

class B
{
  int Value;

  public:
  B(int V) : Value(V) {}

  int GetValue(void) const { return Value;}
};

class A
{
  const B& b;

  public:
  A(const B &ObjectB) : b(ObjectB) {}

  int GetValue(void) { return b.GetValue();}

};


B b(5);

A a1(B(5));

A a2(b);

A a3(B(3));


int main(void)
{
  std::cout << a1.GetValue() << std::endl;
  std::cout << a2.GetValue() << std::endl;
  std::cout << a3.GetValue() << std::endl;

  return 0;
}

用mingw-g++编译并在Windows 7上执行,我得到

6829289
5
1875385008

所以,我从输出中得到的是这两个匿名对象在初始化完成时被销毁,即使它们是在全局上下文中声明的。

我的问题是:是否存在一种方法来确保存储在类中的 const 引用将始终引用有效对象?

【问题讨论】:

  • 缓解这种情况的一种流行方法是使用智能指针。

标签: c++ reference temporary object-lifetime anonymous-objects


【解决方案1】:

你可以在class A做的一件事:

A(B&&) = delete;

这样,尝试从 B 临时构造 A 的两行将无法编译。

这显然不会阻止您提供一些其他 B 对象的生命周期比引用它的 A 对象更短,但这是朝着正确方向迈出的一步,并且可能会遇到一些意外/粗心的滥用行为。 (其他答案已经讨论了设计场景和替代方案 - 我不会涵盖相同的基础/在 插图 场景中引用是否安全(r)已经是一个重要问题。)

【讨论】:

    【解决方案2】:

    不,没有。请记住,引用是底层的指针,通常不控制它们引用的对象的生命周期(请参阅here 了解例外情况,尽管在这种情况下不适用)。我建议只使用一个 B 对象,如果这是您需要的一段代码。

    此外,您可以在 C++11 中使用诸如 shared_ptr 之类的对象,这只会在函数中的指针和对象中的指针都被销毁后才消除该对象。

    【讨论】:

    • 引用不必是底层的指针;并且在任何情况下都没有关系,因为引用和指针具有不同的语义。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-07-09
    • 2010-10-27
    • 2016-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-10
    相关资源
    最近更新 更多