为什么我可以传递对 C++ 中未初始化元素的引用?

les*_*ish 3 c++

为什么下面的代码可以编译通过?

class Demo
{
    public:
    Demo() : a(this->a){}
    int& a;
};

int main()
{
    Demo d;
}
Run Code Online (Sandbox Code Playgroud)

在本例中,a是对整数的引用。但是,当我初始化 Demo 时,我传递了一个对尚未初始化的整数引用的引用。为什么会这样编译?

即使int我使用对具有私有默认构造函数的类的引用而不是 ,这仍然可以编译。为什么这是允许的?

JaM*_*MiT 6

为什么会这样编译?

因为它在语法上是有效的。

C++ 不是一种安全的编程语言。有几个功能可以让您轻松地做正确的事情,但防止某人做错误的事情并不是首要任务。如果你决心做一些愚蠢的事情,没有什么可以阻止你。只要遵循语法,你就可以尝试做任何你想做的事情,无论语义多么荒谬。请记住:编译是关于语法,而不是语义。*

话虽如此,编写编译器的人也并非没有怜悯之心。他们知道常见的错误(可能来自个人经验),并且他们认识到您的编译器能够很好地发现某些类型的语义错误。因此,当您执行某些没有意义的操作(并非所有操作)时,大多数编译器都会发出警告。这就是为什么您应该始终启用编译器警告

警告不会捕获所有逻辑错误,但对于它们捕获的逻辑错误(例如warning: 'Demo::a' is initialized with itselfwarning: '*this.Demo::a' is used uninitialized),您可以节省大量的调试时间。

* 好吧,编译涉及到一些语义,比如赋予标识符一个含义。当我说编译与语义无关时,我指的是更高级别的语义,例如预期的行为。