定义了一个结构体类型
struct A
{
int a;
void func()
{
}
};
结构体在栈中分配
int main()
{
A a;
printf("%d",a.a);
return 0;
}
无法编译 C4700使用了未初始化的局部变量“a”
编译器没有生成默认的构造函数和析构函数
当我手动创建了构造函数和析构函数之后,编译器调用了我创建的构造函数和析构函数。
打印结果为1
结构体在堆中分配
int main()
{
A *a = new A;
printf("%d",a->a);
return 0;
}
编译成功 打印结果 -842150451
编译器没有生成默认的构造函数和析构函数
当我手动创建了构造函数之后,编译器调用了我创建的构造函数
当我手动创建了析构函数之后,编译器并没有调用我的析构函数
并且打印结果仍是 -842150451
当我加入了delete(a);编译器调用了我的析构函数
结构体在堆中分配
int main()
{
A *a = new A();
printf("%d",a->a);
return 0;
}
编译成功 打印结果 0
编译器没有生成默认的构造函数和析构函数
当我手动创建了构造函数之后,编译器调用了我创建的构造函数
当我手动创建了析构函数之后,编译器并没有调用我的析构函数
打印结果变成 -842150451
当我加入了delete(a);编译器调用了我的析构函数
定义了一个类类型
class A
{
public:
int a;
void func()
{
}
};
类在栈中分配
int main()
{
A a;
printf("%d",a.a);
return 0;
}
无法编译 C4700使用了未初始化的局部变量“a”
编译器没有生成默认的构造函数和析构函数
当我手动创建了构造函数和析构函数之后,编译器调用了我创建的构造函数和析构函数。
打印结果为1
类在堆中分配
int main()
{
A* a = new A;
printf("%d", a->a);
return 0;
}
编译成功 打印结果 -842150451
编译器没有生成默认的构造函数和析构函数
当我手动创建了构造函数之后,编译器调用了我创建的构造函数
当我手动创建了析构函数之后,编译器并没有调用我的析构函数
并且打印结果仍是 -842150451
当我加入了delete(a);编译器调用了我的析构函数
类在堆中分配
int main()
{
A* a = new A();
printf("%d", a->a);
return 0;
}
编译成功 打印结果 0
编译器没有生成默认的构造函数和析构函数
当我手动创建了构造函数之后,编译器调用了我创建的构造函数
当我手动创建了析构函数之后,编译器并没有调用我的析构函数
打印结果变成 -842150451
当我加入了delete(a);编译器调用了我的析构函数
总结
1.在没有对任何成员变量做初始化的条件下,编译器不会添加任何构造函数和析构函数
2.如何你没有对任何成员变量初始化,并且是在栈中分配空间的编译会不通过,如果是在堆中分配的会打印未初始化的值
3.如果是在栈中分配空间的,并且创建了构造函数,那么该成员变量会在main函数调用开始被初始化为1,并且,成员变量的初始化并不是由构造函数实现的
4.如果你初始化了成员变量,那么编译器会在运行时创建构造函数并在构造函数内实现该成员变量的初始化
5.如果你创建了析构函数,编译器会对栈中分配空间的销毁时自动调用析构函数,而在堆中分配空间的,只有程序员在调用delete时才会调用
6.在分析以上差异的过程中,struct类型和class类型没有任何区别
7.如果是在堆中分配的,并且是以A()的形式,那么它和A的形式的区别是,编译器会在main函数中多添加几行汇编代码,这几行汇编的意义是初始化所有变量为0,如果你同时创建了构造函数,那么编译器会取消那几行代码,并调用构造函数
8.如果你定义的在栈中分配,想调用无参构造函数请不要使用A a()的形式,直接用A a; 如果你调用的是有参构造函数,请使用A a(1,2)的形式
再次总结
如果你以A()的形式分配空间,要么编译器帮你初始化,要么自己初始化,如果是自己初始化请初始化所有变量
如果使用A的形式分配空间,编译器不会做任何初始化工作
如果选择在栈中分配空间,只要编译通过,编译器会帮你初始化你没初始化的变量。