繁体   English   中英

C++类实例未初始化但没有编译错误,为什么

[英]C++ class instance not initialized but no compile error, why

我的问题是关于以下代码:

#include <stdio.h>
#include <iostream>
#include <string>

using namespace std;

class Blob {
public:
    int age;
    void hello() { printf("hello\n"); }
};

void test_case() {
    Blob a;
    //a.hello();         //(1)
    cout << a.age << endl;
}

int main() {
    test_case();
    return 0;
}

如果我注释掉(1),它编译成功。 如果取消注释 (1),则会发生编译错误,例如在 VS2017 中它会抱怨“使用未初始化的局部变量 'a'”。

我在搜索引擎搜索了一段时间,现在只知道编译器会自动帮我定义默认构造函数的以下4种情况:

  1. 类成员是类的实例(比如 B),并且类 B 定义了默认构造函数

  2. 一个类派生自另一个类(比如 B),并且 B 定义了默认构造函数

  3. 一个类有虚函数

  4. 前 3 种情况的任意组合。

我很好奇,如果我注释掉 (1),编译器会为Blob类添加构造函数的定义吗?

实际上它与注释掉与否无关a.hello(); , Blob总是有一个 生成的默认构造函数,否则Blob a; 不会编译。

(强调我的)

如果没有为类类型(结构、类或联合)提供任何类型的用户声明的构造函数,编译器将始终将默认构造函数声明为其类的内联公共成员。

如果隐式声明的默认构造函数没有定义为delete,则如果odr-used,则由编译器定义(即生成并编译一个函数体),与用户自定义构造函数的作用相同,为空主体和空的初始化列表

结果, a.age默认初始化为不确定值,任何对其的访问(如cout << a.age; )都会导致 UB。

3) 当构造函数初始值设定项列表中未提及基类或非静态数据成员并且调用该构造函数时。

否则,什么都不做:具有自动存储持续时间的对象(及其子对象)被初始化为不确定值

这取决于你的意图; 作为解决方法,您可以添加用户定义的默认构造函数。

class Blob {
public:
    int age;
    void hello() { printf("hello\n"); }
    Blob() : age(42) {}
};

这里有2点。

首先是未定义行为问题。 由于您没有初始化年龄,它包含一个不确定的值,如果您使用它会导致 UB(有关详细信息,请参阅 Songyuanyao 的答案)。 添加额外的指令不会改变任何东西。

接下来是编译器消息。 编译器不需要针对 UB 发出任何警告。 如果它仅在一种情况下引发错误,则您的方法并不是特别一致,但是程序员应该永远不会编写 UB。 所以你不能真的责怪编译器没有发出警告。

TL/DR:不要期望 C++ 编译器在您编写不正确的代码时总是发出警告。 没有警告是必要条件,但不是充分条件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM