你能绑定对未初始化成员的引用吗?

时间:2012-07-05 06:06:33

标签: c++ reference

简短的问题,以下是好的:

struct X
{
    A& x;
    A  y;
    X() : x(y) {}
};

反转结构中两个成员的顺序绝对可以,因为它保证y首先被初始化,但这是否有效或者调用UB?

Moreso,以下是可以的:

struct X
{
   X& x;
   X() : x(*this) {}
};

3 个答案:

答案 0 :(得分:3)

我认为这不会引发未定义的行为。

我没有看到这种情况与此有任何不同:

 int *p = new int;

表达式new int是指向未初始化 int的指针。这里我们用p初始化指针 new int内容未被阅读。

类似地,

 int & r = *p; //or *new int

我们正在使用r初始化引用 *p内容未读取

在这两种情况下,都不会读取内容读取未初始化的变量会调用未定义的行为。在这两种情况下,内容都是未初始化的,而不是地址,我们不是正在阅读内容。

答案 1 :(得分:1)

引用和变量是不同的东西,每个都有自己的“初始化”。

参考的目的是引用something 。唯一的先决条件是something实际存在。无论其状态是否明确,都是另一个故事。

引用的初始化不是UB。它可以是UB的使用,在它被引用的值之前,但这不再是你使用初始化变量时得到的。

不同的是X() :x(*this) {}

这里给出一个函数(x构造函数)指向尚未完全构造的东西的指针。这是“危险的”,因为 - 一般情况下 - 你不知道该函数将对该指针做什么,以及它是否期望它以某种方式“被打开”。可能它只是“存储它以供以后使用”(因此没有问题)可能是它尊重它访问...未经重建的成员! 这是编译器至少应该警告的东西。

当然,在这种特殊情况下(您只是初始化一个引用),它不会成为问题,因为“引用构造函数”不会访问引用的对象。但总的来说不是一个好主意。

答案 2 :(得分:0)

我认为将此问题分成几个其他问题是有意义的:

  1. 这在语法上是否正确,这是否只允许一个实现?
  2. 此代码可以导致崩溃和高级别问题吗?
  3. 编译器应该处理第二个吗?
  4. 我会回答:Y,Y,Y / N.

    我没有看到上面代码示例中的含糊不清。有数百万种语法正确的代码会破坏内存,崩溃等等。这是另一个例子。

    编译器可能会发出警告,因为上面的示例很明显。在具有大量间接,重新定义等的真实场景中,编译器可能会感到困惑。我不会太难以责备它。算法分析是另一个工具的工作,而不是编译器。

    例如,下面的代码非常好:

    int *p = NULL;
    int &r = *p;
    

    这是NULL引用。没什么特别的。

    这是我的2美分。