C++基础知识—关于默认构造函数的一切

C++条款—关于默认构造函数的一切

默认构造函数(defaultconstructor):

默认构造函数是在未提供显示初始值时,用来创建对象的构造函数。如果没有提供任何构造函数,则C++将自动提供默认构造函数,默认构造函数没有参数,因为声明中不包含值。同时,当且仅当没有定义构造函数时,编译器才会提供默认构造函数。为类定义了构造函数后,程序员就必须为它提供默认构造函数,如果提供了非默认构造函数,但没有提供默认构造函数,则在初始化对象时调用默认构造函数是会出错的:

Stack   ww;// 错误

定义默认构造函数有两种方法,一种是让所有的参数都有默认值,一种是通过函数重载的方式来定义另一个构造函数---一个没有参数的构造函数。

总而言之,如果程序没有提供任何构造函数,那么编译器会为程序定义一个默认构造函数;否则,必须自己提供默认构造寒素。默认构造函数可以没有任何参数,如果有,则必须给所有参数都提供默认值。

明白了这些之后,在进入深层次的分析。

什么时候编译器为合成一个default constructor.当编译器需要它的时候!被合成出来的constructor值执行编译器所需要的行动。在没有任何构造函数的类,在进行初始化此类的对象时,编译器合成了一个default constructor,但是这个合成出来的也不会为成员变量进行初始化。如果想为类中的成员变量进行初始化,就必须主动提供一个显示的default constructor.

所以,就产生了这么一说:对于classX,如果没有任何用户定义的构造函数,那么会有一个default constuctor被暗中(implicitly)申明出来…..一个被安装声明出来的default constructor将是一个trivial(无用)的构造函数…..

而一个nontrivial defaultconstructor就是编译器所需要的那种,有四种情况编译器会合成nontrivial default constructor,下面就讨论有四种情况下编译器会合成nontrivialdefault constructor。只有在编译器需要的时候编译器才有合成default constructor。

1、“带有defaultconstructor”的member class object(就是一个类中的一个成员具有defalult  constructor)

如果一个class没有任何constructor,但它内含一个memberobject,而后者有default constructor,那么这个class的implicit default construct即使nontrivial,编译器需要为此class合成出一个defaultconstructor.注意,这个class没有任何constuctor是第一个前提,如果这个class有任何一个构造函数,那么编译器就不会合成default constructor.同时他们是以内联的形式被合成的。合成的默认构造函数只负责初始化具有默认构造函数的member
class object.

同时,如果用户定义了默认构造函数,在这个默认构造函数中没有显示的调用对象成员的默认构造函数,那么这个对象成员的默认构造函数会被合成到这个定义的默认构造函数的。

2、“带有defaultconstructor”的Base class(从具有默认构造函数继承的类)

如果没有任何constructors的class派生自一个“带有defaultconstructor”的base class,那么这个derived class的default constructor会被视为nontiivaial,并因此需要合成出来。

在这种情况下,如果设计者提供多个constructors,但是其中都没有定义default constructor?在这些字自定义的构造函数内,如果没有调用父类的构造函数来初始化父类成员,那么父类的default construcots会被添加进去。它不会合成一个新的default constructor,这是因为已经有了用户自定义的构造函数存在(看最开始的部分就可以明白)的缘故。如果这个子类同时存在着“带有default constructor”的member class objects,那么defalult
constructor也会被调用----在所有base class constructor被调用之后(为什么呢?因为有几成关系的都是先调用子类的构造函数,然后才会初始化子类的成员)

3、“带有一个virtualfunction”的class

不管是继承还是声明,只要在此类中存在了virtual function,同时缺乏用户自定义的构造函数,编译器会合成一个default constructor

4、“带有一个virtual baseclass”的class

如果没有任何用户自定义的函数,但是这个类继承了virtual base class,那么编译器会合成一个default constructor

总结:上述四种情况下,编译器必须为没有生命构造函数的类合成一个default constructor,C++标准把那些合成物成为隐式有用默认构造函数(implicitnontrivial default constructors),但是合成出来的构造函数只能满足编译器的需要。他们能完成任务,是借着“调用成员对象或基类的default constructor”或是“为灭一个对象初始化其虚拟函数机制或虚基类机制”而完成。至于没有存在那四种情况而又没有任何构造函数的类,我们说他们拥有的是implicit trivial
default constructor(隐式无用默认构造函数)。

在合成的defaultconstructor中,只有base class subobjects和member class objects会被初始化。所有其他的成员都不会被初始化。这些初始化操作对程序而言或许有需要,但对编译器则并非必要。

时间: 2024-08-01 18:12:54

C++基础知识—关于默认构造函数的一切的相关文章

javascript基础知识--什么是构造函数?什么是实例化对象?

前言--讲在前面 我想有很多以前很少接触后台编程语言的初学者朋友跟我一样,对javascript里面一系列的“名词”搞的一头雾水.好像大概知道讲的是什么,但其实理解的还是不清楚:我想,学习任何一种知识,首当其冲应该把最基本的名词解释搞清楚(知道它讲的到底是什么,有助于我们更好的理解它.)即知其然知其所以然,这样对以后的进阶学习是很有帮助的.下面的简单讲一下我自己对这样一些看似不重要但又不得不清楚的知识点的理解.(若有出入,欢迎指正) 1.什么是构造函数 构造函数 ,是一种特殊的方法.主要用来在创

javascript的基础知识及面向对象和原型属性

自己总结一下javascript的基础知识,希望对大家有用,也希望大家来拍砖,毕竟是个人的理解啊 1.1 类型检查:typeof(验证数据类型是:string) var num = 123; console.log(typeof num); // 1.2 in 运算符 作用:判断指定属性是否存在于指定的对象中. 如果指定的属性存在于指定的对象中,则 in 运算符会返回 true. 语法: 属性 in 对象 返回值:true 或者 false 示例: var obj = { age: 18 };

C#基础知识篇(五)-----------C#笔记

一.值类型和引用类型 1>值类型和引用类型将我们学过的数据类型划分成了两部分. 划分的依据是不同类型的数据在内存中(堆栈)存储的结构不同. 2>值类型:所有的数值类型:long int short byte ulong uint ushort sbyte decimal duoble float char bool 枚举 结构 3>引用类型:string,arry(数组),类(class) 4>不管是值类型还是引用类型赋值都是将数据copy一份将副本赋给变量,不同的是值类型拷贝的是

JS基础知识回顾:引用类型(一)

在ECMAScript中引用类型是一种数据结构,用于将数据和功能组织在一起,而对象时引用类型的一个实例. 尽管ECMAScript从技术上讲是一门面向对象的语言,但它不具备传统的面向对象语言所支持的类和接口等基本结构,所以虽然说引用类型与类看起来想死,但他们并不是相同的概念. 不过引用类型有的时候也可以被称为对象定义,因为他们描述的是一类对象所具有的属性和方法. 新对象是使用new操作符后跟一个构造函数来实现的,构造函数本身就是一个函数,只不过该函数时处于创建新对象的目的而定义的. ECMASc

PHP中oop面向对象基础知识(一)

                                                                                    OOP 基础知识汇总(一) >>>你需要了解以下概念面向对象&面向过程概念:  面向过程:专注于解决一个问题的过程.面向过程的最大特点,是由一个一个的函数去解决处理这个问题的一系列过程.  面向对象:专注于由哪个对象来处理一个问题.面向对象的最大特点,是有一个个具有属性和功能的类,从类中拿到对象,进而处理问题. [

Java__线程---基础知识全面实战---坦克大战系列为例

今天想将自己去年自己编写的坦克大战的代码与大家分享一下,主要面向学习过java但对java运用并不是很熟悉的同学,该编程代码基本上涉及了java基础知识的各个方面,大家可以通过练习该程序对自己的java进行一下实战. 每个程序版本代码中,都附有相关注释,看完注释大家就可以对本程序设计有个很明显的思路.真的很有趣,想对java重新温习的同学完全不必再对厚厚的java基础书籍进行阅读了,在跟着本次代码练习并分析后,大家一定会对java各方面基础知识 尤其是线程的知识有更深一步的了解!!! 本次坦克大

20151024_004_C#基础知识(C#中的访问修饰符,继承,new关键字,里氏转换,is 和 as,多态,序列化与反序列化)

1:C#中的访问修饰符 public: 公共成员,完全公开,没有访问限制. private: 私有的,只能在当前类的内部访问. protected: 受保护的,只能在当前类的内部以及该类的子类中访问. internal: 只能在当前项目中访问,在同一个项目中,internal和public的权限是一样的. protected internal: protected + internal权限. 1.1:能够修饰类的访问修饰符只有两个: public / internal 1.2:接口中的成员不允许

Java并发(基础知识)—— Executor框架及线程池

在Java并发(基础知识)—— 创建.运行以及停止一个线程中讲解了两种创建线程的方式:直接继承Thread类以及实现Runnable接口并赋给Thread,这两种创建线程的方式在线程比较少的时候是没有问题的,但是当需要创建大量线程时就会出现问题,因为这种使用方法把线程创建语句随意地散落在代码中,无法统一管理线程,我们将无法管理创建线程的数量,而过量的线程创建将直接使系统崩溃. 从高内聚角度讲,我们应该创建一个统一的创建以及运行接口,为我们管理这些线程,这个统一的创建与运行接口就是JDK 5的Ex

C#基础知识篇(四)-----------C#笔记

一.类 1. 什么叫做类? 类是具有相同特征的一类事物统称.所以类是一种抽象,即不是一个实体(我们把类看做模板). 2. 什么叫做对象? 对象是根据类的模板创造出来的一个实体,它具有类里所有的特征,一个也多不得,一个也少不得.少了就不叫这个类的成员了,多了也不是!假如张三有变身这个功能,那么张三就不属于人. 记住对象是根据模板创建的,模板有什么它就有什么,不会多也不会少! 3. 什么叫做字段(或者是成员变量)? 我们把定义在方法的外面,类的里面(即:类中)的变量称之为字段或者说是成员变量. 4.