【C++对象模型】构造函数语意学之一 默认构造函数

 

默认构造函数,如果程序员没有为类定义构造函数,那么编译器会在【需要的时候】为类合成一个构造函数,而【需要的时候】分为程序员需要的时候和编译器需要的时候,程序员需要的时候应该由程序员来做工作,编译器需要的时候则由编译器来做工作。

 

C++中,全局变量 / 对象的内存会被清零(如果类对象没有程序员定义的构造函数的时候), 而堆heap 或 栈stack上的变量或对象则不会被清零,其内存只取决于上一次这段内存的值。

 

而编译器什么情况下会为类合成默认构造函数呢?
会在以下四种情况合成默认的构造函数:

1、类中有一个或多个类对成员,而类对象成员又有一个默认的构造函数(不管这个默认构造函数是显式声明的还是由编译器合成的)

2、当类继承子一个基类,而这个基类有一个默认构造函数(不管这个默认构造函数是显式声明的还是由编译器合成的)

3、当类声明了一个或多个虚函数时

4、当类派生自一个继承链,其中有一个或多个虚基类时

 

 

 

先来讨论第一种情况:类中有一个或多个类对成员,而类对象成员又有一个默认的构造函数

如果类中这种情况,则编译器会为类合成一个默认的构造函数,其构造函数内部做到工作只是调用该对象成员的默认构造函数,这个时候就是编译器【需要的时候】,当有多个对象成员时,编译器调用他们构造函数的顺序是按照他们在类中声明的顺序。

对于该类的其他简单成员,编译器不会对其进行初始化,这部分工作则需要又程序员来完成。

 

 二、当类继承子一个基类,而这个基类有一个默认构造函数

 如果程序员没有为该类声明构造函数(而非默认构造函数),那么编译器会为该类合成一个默认构造函数。

特别的,当该了声明了若干个构造函数,而没有默认构造函数时,编译器则不会为该了合成默认构造函数,此时,编译器会去扩展现有的构造函数,在内部先去调用父类的默认构造函数,如果同时有类对象成员,那么去调用该类对象的默认构造函数,最后调用程序员的手动初始化代码。

 

三、当类声明了一个或多个虚函数时

四、当类派生自一个继承链,其中有一个或多个虚基类时

这两种情况都涉及到虚函数表指针vtpr的问题,所以都需要生成默认的构造函数来设置vtpr的合法值。

扩张行为:一个虚函数表(存放虚函数的地址), 一个虚函数表指针(指向虚函数表)

 

PS:两个误解:1任何类如果没有定义默认构造函数则编译器会合成一个出来   2编译器合成出来的默认构造函数会显式设定类中每个数据成员的默认值。

这两个都是错误的!

 

 

 

 

posted on   崔好好  阅读(363)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示