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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

这两个都是错误的!

【C++对象模型】构造函数语意学之一 默认构造函数的更多相关文章

  1. 《深度探索C++对象模型》第二章 | 构造函数语意学

    默认构造函数的构建操作 默认构造函数在需要的时候被编译器合成出来.这里"在需要的时候"指的是编译器需要的时候. 带有默认构造函数的成员对象 如果一个类没有任何构造函数,但是它包含一 ...

  2. C++ 合成默认构造函数的真相

    对于C++默认构造函数,我曾经有两点误解: 类如果没有定义任何的构造函数,那么编译器(一定会!)将为类定义一个合成的默认构造函数. 合成默认构造函数会初始化类中所有的数据成员. 第一个误解来自于我学习 ...

  3. java中创建对象中使用默认构造函数的注意点

    public class Test3 {   private int n;   Test3() {      System.out.println("调用默认构造器");   }  ...

  4. C++的默认构造函数

    待看文章:C++ 合成默认构造函数的真相 默认构造函数指不带参数或者所有参数都有缺省值的构造函数!!! 类的默认构造函数可以使得在实例化该类的对象时不用提供参数,但是类也可以不含默认构造函数,这样在实 ...

  5. C++ 构造函数与默认构造函数

    构造函数:C++用于构建类的新对象时需要调用的函数,该函数无返回类型!(注意:是“无”! 不是空!(void)). 默认构造函数:未提供显式初始值时,用来穿件对象的构造函数. 以上是二者的定义,但是单 ...

  6. 【C++对象模型】构造函数语意学之二 拷贝构造函数

    关于默认拷贝构造函数,有一点和默认构造函数类似,就是编译器只有在[需要的时候]才去合成默认的拷贝构造函数. 在什么时候才是[需要的时候]呢? 也就是类不展现[bitwise copy semantic ...

  7. C++对象模型的那些事儿之三:默认构造函数

    前言 继前两篇总结了C++对象模型及其内存布局后,我们继续来探索一下C++对象的默认构造函数.对于C++的初学者来说,有如下两个误解: 任何class如果没有定义default constructor ...

  8. C++对象模型——默认构造函数的合成

    最近在学习C++对象模型,看的书是侯捷老师的<深度探索C++对象模型>,发现自己以前对构造函数存在很多误解,作此笔记记录. 默认构造函数的误解 1.当程序猿定义了默认构造函数,编译器就会直 ...

  9. C++对象模型(一):The Semantics of Constructors The Default Constructor (默认构造函数什么时候会被创建出来)

    本文是 Inside The C++ Object Model, Chapter 2的部分读书笔记. C++ Annotated Reference Manual中明确告诉我们: default co ...

随机推荐

  1. MyBatis,动态传入表名,字段名的解决办法

    转载:http://luoyu-ds.iteye.com/blog/1517607 今天做项目,遇到的问题就是需求修改数据表的记录,而且字段名都不是固定的,也就是说是需要通过参数传入的, 本来这也不是 ...

  2. 理解maven

    1.理解“仓库” 首次运行完mvn -version后,会在用户目录下创建一个.m2的目录(比如:C:\Users\当前用户名\.m2\),这个目录是maven的“本地仓库”,仓库是maven中一个很 ...

  3. java nio知识点总结

    1.NIO是Java 4里面提供的新的API,目的是用来解决传统IO的问题.是用来解决传统io的问题的. 用来解决传统io的问题的.用来解决传统io的问题.阻塞的. 2.传统IO中,Stream是单向 ...

  4. 63. Unique Paths II

    题目: Follow up for "Unique Paths": Now consider if some obstacles are added to the grids. H ...

  5. 利用 img 和 script 发送跨域请求

    利用img.src可以发送http请求,但是发送http请求不是img.src的真正用意. 同样,用script.src去请求jsonp格式的接口数据也不是script元素的最初设计用途. 但是这些歪 ...

  6. 使用exe4j把JAVA GUI程序打包成exe文件时遇到的问题

    1.把项目打包成jar文件时,只要勾选src目录就行了,其他的比如资源文件和jar包是不能添加进去的. 2.在D盘建一个文件夹,最好与项目同名,然后把打包好的jar包放进去,其他资源文件(图片之类的) ...

  7. MongoDB 安装和即基本操作

    http://www.mongodb.org/ Agile and Scalable MongoDB (from "humongous") is an open-source do ...

  8. poj 2777 Count Color(线段树 区间更新)

    题目:http://poj.org/problem?id=2777 区间更新,比点更新多一点内容, 详见注释,  参考了一下别人的博客.... 参考博客:http://www.2cto.com/kf/ ...

  9. uva live 6170

    Esspe-Peasee Esspe-Peasee is an ancient game played by children throughout the land of Acmania. The ...

  10. 一个简单的ORM制作(SQL帮助类)

    一个简单的ORM制作大概需要以下几个类: SQL执行类 CURD操作类 其他酱油类 先从SQL执行类说起,可能会涉及数据库的迁移等问题,所以需要定义一个接口以方便迁移到其他数据库, 事务没提供命名,若 ...