【C++对象模型】构造函数语意学之一 默认构造函数
默认构造函数,如果程序员没有为类定义构造函数,那么编译器会在【需要的时候】为类合成一个构造函数,而【需要的时候】分为程序员需要的时候和编译器需要的时候,程序员需要的时候应该由程序员来做工作,编译器需要的时候则由编译器来做工作。
C++中,全局变量 / 对象的内存会被清零(如果类对象没有程序员定义的构造函数的时候), 而堆heap 或 栈stack上的变量或对象则不会被清零,其内存只取决于上一次这段内存的值。
而编译器什么情况下会为类合成默认构造函数呢?
会在以下四种情况合成默认的构造函数:
1、类中有一个或多个类对成员,而类对象成员又有一个默认的构造函数(不管这个默认构造函数是显式声明的还是由编译器合成的)
2、当类继承子一个基类,而这个基类有一个默认构造函数(不管这个默认构造函数是显式声明的还是由编译器合成的)
3、当类声明了一个或多个虚函数时
4、当类派生自一个继承链,其中有一个或多个虚基类时
先来讨论第一种情况:类中有一个或多个类对成员,而类对象成员又有一个默认的构造函数
如果类中这种情况,则编译器会为类合成一个默认的构造函数,其构造函数内部做到工作只是调用该对象成员的默认构造函数,这个时候就是编译器【需要的时候】,当有多个对象成员时,编译器调用他们构造函数的顺序是按照他们在类中声明的顺序。
对于该类的其他简单成员,编译器不会对其进行初始化,这部分工作则需要又程序员来完成。
二、当类继承子一个基类,而这个基类有一个默认构造函数
如果程序员没有为该类声明构造函数(而非默认构造函数),那么编译器会为该类合成一个默认构造函数。
特别的,当该了声明了若干个构造函数,而没有默认构造函数时,编译器则不会为该了合成默认构造函数,此时,编译器会去扩展现有的构造函数,在内部先去调用父类的默认构造函数,如果同时有类对象成员,那么去调用该类对象的默认构造函数,最后调用程序员的手动初始化代码。
三、当类声明了一个或多个虚函数时
四、当类派生自一个继承链,其中有一个或多个虚基类时
这两种情况都涉及到虚函数表指针vtpr的问题,所以都需要生成默认的构造函数来设置vtpr的合法值。
扩张行为:一个虚函数表(存放虚函数的地址), 一个虚函数表指针(指向虚函数表)
PS:两个误解:1任何类如果没有定义默认构造函数则编译器会合成一个出来 2编译器合成出来的默认构造函数会显式设定类中每个数据成员的默认值。
这两个都是错误的!
【C++对象模型】构造函数语意学之一 默认构造函数的更多相关文章
- 《深度探索C++对象模型》第二章 | 构造函数语意学
默认构造函数的构建操作 默认构造函数在需要的时候被编译器合成出来.这里"在需要的时候"指的是编译器需要的时候. 带有默认构造函数的成员对象 如果一个类没有任何构造函数,但是它包含一 ...
- C++ 合成默认构造函数的真相
对于C++默认构造函数,我曾经有两点误解: 类如果没有定义任何的构造函数,那么编译器(一定会!)将为类定义一个合成的默认构造函数. 合成默认构造函数会初始化类中所有的数据成员. 第一个误解来自于我学习 ...
- java中创建对象中使用默认构造函数的注意点
public class Test3 { private int n; Test3() { System.out.println("调用默认构造器"); } ...
- C++的默认构造函数
待看文章:C++ 合成默认构造函数的真相 默认构造函数指不带参数或者所有参数都有缺省值的构造函数!!! 类的默认构造函数可以使得在实例化该类的对象时不用提供参数,但是类也可以不含默认构造函数,这样在实 ...
- C++ 构造函数与默认构造函数
构造函数:C++用于构建类的新对象时需要调用的函数,该函数无返回类型!(注意:是“无”! 不是空!(void)). 默认构造函数:未提供显式初始值时,用来穿件对象的构造函数. 以上是二者的定义,但是单 ...
- 【C++对象模型】构造函数语意学之二 拷贝构造函数
关于默认拷贝构造函数,有一点和默认构造函数类似,就是编译器只有在[需要的时候]才去合成默认的拷贝构造函数. 在什么时候才是[需要的时候]呢? 也就是类不展现[bitwise copy semantic ...
- C++对象模型的那些事儿之三:默认构造函数
前言 继前两篇总结了C++对象模型及其内存布局后,我们继续来探索一下C++对象的默认构造函数.对于C++的初学者来说,有如下两个误解: 任何class如果没有定义default constructor ...
- C++对象模型——默认构造函数的合成
最近在学习C++对象模型,看的书是侯捷老师的<深度探索C++对象模型>,发现自己以前对构造函数存在很多误解,作此笔记记录. 默认构造函数的误解 1.当程序猿定义了默认构造函数,编译器就会直 ...
- C++对象模型(一):The Semantics of Constructors The Default Constructor (默认构造函数什么时候会被创建出来)
本文是 Inside The C++ Object Model, Chapter 2的部分读书笔记. C++ Annotated Reference Manual中明确告诉我们: default co ...
随机推荐
- Intellij 导入play framework 项目
新建一个项目 play new helloworld IshallbeThatIshallbe:~ iamthat$ mkdir temp IshallbeThatIshallbe:~ iamthat ...
- ZipArchive框架的文件压缩和解压
导入第三方框架ZipArchive之后还要在系统库文件中导入一个如下文件(搜索libz出来的任何一个都可以) 导入的头文件是#import "Main.h" 文件压缩 -(vo ...
- iOS 开发--开源图片处理圆角
概述 开源项目名称:HYBImageCliped 当前版本:2.0.0 项目用途:可给任意继承UIView的控件添加任意多个圆角.可根据颜色生成图片且可带任意个圆角.给UIButton设置不同状态下的 ...
- Xamarin.Android 入门之:Xamarin快速入门
一. 准备工作 1.新建一个项目取名为phoneword 2.在项目创建好之后,让我们展开“Resources”文件夹然后找到并打开该文件夹下的“layout”文件夹,双击main.axml在Andr ...
- HTML5 编辑 API 之 Range 对象(二)
1.Range.cloneContents()The Range.cloneContents() returns a DocumentFragment copying the objects of t ...
- C++中全局变量的那些事儿
C/C++中的变量分为全局变量.静态全局变量.局部变量和静态局部变量,在<C/C++中静态局部变量的特点与应用>中我们介绍过静态局部变量,今天我们的目标是全局变量. 单个文件中的全局变量 ...
- [UESTC1059]秋实大哥与小朋友(线段树, 离散化)
题目链接:http://acm.uestc.edu.cn/#/problem/show/1059 普通线段树+离散化,关键是……离散化后建树和查询都要按照基本法!!!RE了不知道多少次………………我真 ...
- Linux查看所有用户用什么命令
用过Linux系统的人都知道,Linux系统查看用户不是会Windows那样,鼠标右键看我的电脑属性,然后看计算机用户和组即可. 那么Linux操作系统里查看所有用户该怎么办呢?用命令.其实用命令就能 ...
- 使用截图方式将Excel导出为PNG图片的不可行性
博主前面一篇文章使用了JAVA的Robot机制 模拟打开Excel然后Robot移动到指定区域,截图并生成PNG格式图片 试图使用这种方式将复杂的Excel报表转化成无差别的PNG图片 但是这种方式遇 ...
- Alpha、Beta、RC、GA版本的区别
Alpha:是内部测试版,一般不向外部发布,会有很多Bug.一般只有测试人员使用. Beta:也是测试版,这个阶段的版本会一直加入新的功能.在Alpha版之后推出. RC:(Release Candi ...