【问题标题】:value-initialization of a const member referenceconst 成员引用的值初始化
【发布时间】:2010-11-10 19:21:01
【问题描述】:

我正在查看以下形式的代码:

class foo
{
  public:
    foo() {}

  //...
};

class bar
{
  public:
    bar() : ref() {}

  private:
    const foo &ref;
};

以这种方式使用临时变量初始化引用是否正确?我知道可以用临时变量初始化一个局部变量的 const 引用,这样做可以延长临时变量的生命周期,例如

const foo &tmp = funcThatReturnsByValue(); //OK

但是,相关initialize reference in initialization list 的答案之一表明“短期”和“长期”引用之间存在差异,并且如上所述初始化ref 是未定义的行为(即使@ 987654326@ 是 const 引用)。

标准中的 12.2.5 部分表示,“在构造函数的 ctor-initializer 中临时绑定到引用成员将持续存在,直到构造函数退出。”这是描述这种情况吗?

【问题讨论】:

  • 您能否修复您的代码,使其实际上涉及临时代码?
  • ref() 没有将 ref 绑定到 foo 的临时实例?对不起,如果我的术语不准确......我正在尽我所能理解这段代码 sn-p。
  • 也许这条评论毫无价值(我不知道你正在查看这段代码的上下文),但如果ref 是一个指针,问题就会消失。关键是引用不能被值初始化,但指针可以(它们被零初始化)。此外,大多数编译器(至少是 MSVC)都会发出警告,因为它无法生成默认赋值运算符。作为指导,只要你想要一个引用成员,你实际上需要一个指针......
  • 临时生命周期的延长似乎并不那么可靠,毕竟:stackoverflow.com/questions/2604206/…。它似乎是为了让在类型转换期间创建的临时对象能够正常工作而设计的,但并不打算用于其他用途。
  • @James McNellis:该规则仅适用于结果是真正的临时调用者(因此提问者将函数命名为funcThatReturnsByValue())如果函数返回通过引用(或其他东西)而不是按值,那么它是一个临时的,其生命周期由其他东西(例如被调用的函数)控制,并且在返回之前会被销毁。因此,temporary 的含义很窄,对于 C++ 编译器圈外的人来说并不明显。对于任何代码审查者来说,它也不会很明显。

标签: c++ reference


【解决方案1】:

此代码格式错误。您不能默认初始化或值初始化引用。

如果您实际上在ref() 中有一个表达式,那么是的,12.2.5 将适用,并且在构造函数退出时临时将被销毁。

【讨论】:

  • 你会想,但我无法让 GCC 4.3.4 真正做到这一点。
【解决方案2】:

您的示例不是创建临时的 - 为此您需要更改为:

    bar() : ref(foo()) {} 

现在您将引用绑定到一个临时对象,该临时对象将在构造函数结束时被销毁。您的参考将无效,这不是一件好事。

【讨论】:

    【解决方案3】:

    我猜你想做的是:

    bar() : ref(foo()) {}
    

    但不要天真地认为临时的生命周期会延长,直到有对它的引用。不,实际上不是。因此,无论是否为 const,您都应该使用普通对象初始化引用。

    【讨论】:

      猜你喜欢
      • 2015-04-27
      • 2015-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-08
      • 2010-12-14
      相关资源
      最近更新 更多