在成员初始值设定项列表中,我可以创建对不在列表中的成员变量的引用吗?

时间:2018-04-25 10:43:57

标签: c++ initialization

考虑:

#include <string>
#include <iostream>

class Foo
{
     public:
         Foo( char const * msg ) : x( y ) 
         {
             y = msg;
         }

         std::string const & x;

     private:
         std::string y;
};

int main( int argc, char * argv[] )
{
    if ( argc >= 2 )
    {
        Foo f( argv[1] );
        std::cout << f.x << std::endl;
    }
}

这会编译并打印出第一个参数......但我怀疑它是否真的&#34;合法&#34; /格式良好。我知道初始化列表应该按照它们在类中声明的顺序初始化变量,以免你引用尚未初始化的变量。但是成员变量不在初始化列表中呢?我可以安全地创建对它们的展示吗?

(当然,这个例子毫无意义。只是为了澄清我在谈论的内容。)

3 个答案:

答案 0 :(得分:21)

你可以这样做 1 因为:

  1. xy都在范围内([basic.scope.class]/1)。
  2. 由于您在构造函数开始执行后获取引用([class.cdtor]/1)并且已经获得y的{​​{1}}存储空间,因此该引用可以绑定到y }。
  3. 在构造函数的复合语句中使用该引用(在成员初始化完成后)也没问题。这是因为y被认为是初始化的,x现在指的是生命周期已经开始的对象。

    <子> 1 - 对于语言律师来说,这是一个警告。从技术上讲,引用需要绑定到有效对象([basic.life]/7),这意味着它的生命周期已经开始。但是,就像[dcl.ref]/5详细信息一样,预计会有效!有问题的措辞和可能的解决方案在Core Language issue 363中讨论(由@ T.C。在删除的评论中提供)。标准中存在一个错误,但您的代码意图很好,并且实现通常都会意识到它。

答案 1 :(得分:3)

  

但是不在初始化列表中的成员变量呢?

变量是否在初始化列表中,在这方面无关紧要。如果变量不在初始化列表中(也没有默认成员初始值设定项),则默认初始化。

yx之后初始化。这不是因为成员初始化列表,因为成员初始化列表不会影响成员初始化的顺序。成员按其声明的顺序初始化。

但是,y是否已初始化也无关紧要。它很好地在成员初始化之前将引用绑定到成员(除了绑定到未初始化成员的虚拟基础;这将具有UB)。

关于安全性(或者更准确地说正确性),我建议您花些时间考虑复制Foo时会发生什么。 x会引用什么?那是班级用户所期望的吗?

答案 2 :(得分:0)

  

我可以安全地创建对它们的展示吗?

是的,你可以。无论是否初始化,成员y的存储地址都是已知的,因此x(y)引用初始化是合法的。