2

我有以下代码:

class A {
 public:
  A() { }
};

class B {
 private:
  const A &a;

 public:
  B() : a() { }
  B(const A &ina) : a(ina) { }
};

编译结果如下:

ab.cpp:在构造函数'B::B()'中:

ab.cpp:11:警告:'const A& B::a' 的默认初始化,它具有引用类型

为什么这会导致警告,我该如何解决?

4

4 回答 4

13

C++ 语言中的引用可以被认为是其他对象的“替代名称”。名称始终指代一个对象,没有该对象就不能存在,即引用不能“引用任何内容”。这意味着引用必须在创建引用时立即绑定到目标对象,并且只要该引用存在,就一直绑定到该对象。该语言专门设计用于尽可能地执行该规则。对于非聚合类类型中的引用成员,这些成员必须在构造函数初始化器列表中显式初始化。

严格来说,调用默认初始化引用的程序是格式错误的。在日常命名中,它应该是一个“错误”,而不是一个“警告”。所以,这里真正的“为什么”是为什么你的编译器只发出警告(尽管形式上任何诊断消息都足以报告格式错误的代码)。

于 2013-08-21T21:11:55.000 回答
5

从标准:

8.5.3 参考文献 [dcl.init.ref]

  1. 声明为 T& 或 T&& 的变量,即“对 T 类型的引用”(8.3.2),应由 T 类型的对象或函数或可转换为 T 的对象初始化。

  2. [...]

  3. 初始化器只能在参数声明 (8.3.5)、函数返回类型声明、类定义中的类成员声明 (9.2) 以及显式指定 extern 说明符的情况下省略引用用过的。

的构造函数B是错误的,因为它在内部调用了引用的默认构造函数,这是不可能的。

必须在构造函数的成员初始化列表中初始化引用成员。这就是为什么您的默认构造函数格式错误的原因。

于 2013-08-21T21:19:57.133 回答
2

是UB。必须始终初始化引用。

于 2013-08-21T21:09:07.580 回答
1

引用应始终引用变量。因此,B 的第一个构造函数中的默认初始化没有意义。实际上,具有默认初始化的引用与具有根本未初始化的指针相同:两者都引用(或指向)内存中的随机位置。因此发出警告。

于 2013-08-21T21:11:14.703 回答