C++中关于默认构造函数(Default Constructor)

发布时间 2023-04-28 15:47:45作者: 严_青

读<<深度探索C++对象模型>>,第二章介绍了默认构造函数,自觉知识点虽基础但是很是被忽略,故作此文记录.

关于基础概念不做介绍,先看代码

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

class Sample{
    
public:
    int intVal;
};

class Foo {
public:
    Foo(int a = 1000): intVal(a){

    };
    int intVal;
};

class Bar {
    
public:
    Foo foo;
    Sample sample;
    std::string str;
    int intVal;
};

void init(){
    Bar bar;
    printf("bar.foo.intVal: %d\n",bar.foo.intVal);
    printf("bar.sample.intVal: %d\n",bar.sample.intVal);
    printf("bar.str: %s\n", bar.str.c_str());
    printf("bar.intVal: %d \n",bar.intVal);
}

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

代码简单明了,就是初始一个Bar对象,打印对象的 data member.再拷贝到IDE中之前,不妨猜想一下输出结果

假设已经思考了一段时间,
看下运行结果

运行环境 版本13.3.1 (22E261) Xcode Version 14.3 (14E222b) Apple Clang

foo uninit
bar.foo.intVal: 1000
bar.sample.intVal: 0
bar.str: 
bar.intVal: -1074793664 
Program ended with exit code: 0

一次试验不足以总结出什么结论,先分析看:
由输出可知:

 * Bar成员foo调用了我们自己写的构造函数,将intVal初始化为1000
 * Bar成员sample默认初始化了其member intVal为0
 * Bar成员intVal 未初始化,值为随机值(可能多次输出相同)
 * Bar成员str 初始化为空字符串

接下来将代码放到Windows平台运行

运行环境: window11 vs2019 编译器 对应vs2019的msvc++

foo uninit
bar.foo.intVal: 1000
bar.sample.intVal: -12903328372
bar.str: 
bar.intVal: -7392214732 
Program ended with exit code: 0

通过对比:
* Bar的intVal成员未初始化
Sample的intVal成员未初始化

大概总结一下:
编译器对于未初始化的字符串member 会自动初始化为空字符
不同编译器对于intVal的初始化行为是不一样的
编译器会默认调用有构造函数的对象构造方法
不要相信编译器