引言

构造函数是c++中的一个比较难的语法知识点。编程实践中,由于在很多情况下可以不显示定义构造函数,或者,虽然定义构造函数的方式并不十分适当,但是程序也能正常运行,故而并不是特别引起开发者的重视。

实际上,构造函数对C++语言十分重要,深入理解构造函数既能加深对很多C++高级语法,尤其是编译时,运行时,类的实例化和继承等概念的理解,而且能帮助我们写出更加健壮的代码。

本文从C++构造函数的概念出发,研究构造函数相关的理论和应用。包括构造函数的分类、形式、编译、运行(调用)等。在叙述的同时,辅以一些程序例子,并在一些易混淆的地方与Java、C#的构造函数进行对比。

  本文中一些知识点来源于一些专业著作和网上资源,文章结尾有对这些资源的引用。

构造函数的概念的语法形式

构造函数(constructor),是类的成员函数的一种(关于构造函数属不属于类的成员函数,这里不做深究。很多资料将构造函数称为构造子,尤其在Java和C#中,将构造函数称为constructor,而将类的其它函数称作方法 - method),其作用是在定义类的实例时执行初始化操作(例如类成员变量的初始化、赋值,以及一些其它的操作)。

  我们知道,函数有三要素:函数名、形参列表和返回值。对于类成员函数来说,可能还包含其它修饰符,比如访问修饰符(public,protected,private),静态修饰符(static)等。而对于构造函数来说,跟普通的成员函数相比最大的不同如下:

  1. 构造函数必须与类同名;

  2. 构造函数没有返回值。

  3. 构造函数不能被直接显示调用。构造函数会在实例化(instantiate)类的时候被运行时调用,但不能被程序员显示调用(也可以理解为,当在代码中创建一个类的实例时,就是在调用构造函数)。

  例如:

class DemoClassA{
public:
DemoClassA(){}
DemoClassA(int a):m_a(a){
}
private:
int m_a;
};

  上面的代码只是一个简单的例子,可以看到,定义了两个构造函数,其中一个时无参的默认构造函数,另外一个时重载(overloaded)的含参构造函数,并用构造函数初始化值列表对类的成员变量进行了初始化。

默认构造函数,合成默认构造函数

  没有形参列表的构造函数称为默认构造函数

  开发者在定义一个类时,可以选择显示定一个构造函数(或者显示定义多个重载的构造函数),也可以不显示定义构造函数。如果开发者没有显示定义任何的构造函数(包括默认构造函数),则编译器会为类生成一个默认的构造函数,称为合成默认构造函数

  如果没有特殊需求,建议开发者显示定义默认构造函数(尤其在已经定义了非默认构造函数时),原因如下:

  1. 很多情况下,创建一个类的实例时,调用程序并不急于(或者不能够)对类的成员变量进行有意义的初始化,而是在运行过程中通过类似Java的SetXXX或者C#的属性的方式对成员变量赋值,因而,保留类的默认构造函数,可以方便类的使用者在初始化时无需考虑成员变量的初始化问题。除非一个类在设计时,就明确要求在其实例化时通过构造函数获得一些参数值,以执行一些特定操作(比如成员变量赋值,逻辑判断等),此时应当定义非默认构造函数,并有意不定义默认构造函数,或者定义一个私有的默认构造函数,来达到禁止利用默认构造函数实例化的目的。

  2. 当类的成员变量中包含基本数据类型或者复合数据类型(例如引用或者指针),这一点上,类成员变量的初始化规则跟函数局部变量的初始化规则相同。

  

构造函数的定义和重载

介绍构造函数的重载规则前,先简要梳理一下普通成员函数的重载和调用规则。

构造函数由于要初始化成员变量,故而不能被修饰成const成员函数。

构造函数初始值列表、类内初始值

类内初始值是指在定义成员变量时赋给成员的初始值,包括在成员变量声明之处给的初始值,或者在类外定义的初始值。

需要注意,在C++中,初始化和赋值是两个不同的概念。

构造函数的编译和运行

C++类的构造函数编译规则(参考对比Java和C#构造函数的编译和运行规则)

编译时,编译器知道一个类实例化时所需要的内存空间大小。

很多编译器能对成员变量进行优化,故而在c语言中定义一个结构体时需要注意的字节对齐问题,C++编译器能够帮助解决。

构造函数和析构函数

析构函数可以用virtual修饰,构造函数不能

参考资料

1. C++ Primer(中文版 第5版),Stanley B. Lippman,Josée Lajoie,Barbara E. Moo 著;王刚,杨巨峰 译;叶劲峰,李云,刘未鹏 等 校

2.  http://blog.csdn.net/grief_of_the_nazgul/article/details/45741849

3.

C++构造函数知识点整理(C++11标准)的更多相关文章

  1. 合成的默认构造函数定义为delete的一种情况(针对C++11标准)

    1. 默认初始化 如果定义变量时没有指定初值,则变量会被默认初始化,此时变量被赋予了"默认值". 对于类类型的变量来说,初始化都是依靠构造函数来完成的.因此,即使定义某个类的变量( ...

  2. JS知识点整理(二)

    前言 这是对平时的一些读书笔记和理解进行整理的第二部分,第一部分请前往:JS知识点整理(一).本文包含一些易混淆.遗漏的知识点,也会配上一些例子,也许不是很完整,也许还会有点杂,但也许会有你需要的,后 ...

  3. C++ Primer中文版(第5版)(顶级畅销书重磅升级全面采用最新 C++ 11标准)

    C++ Primer中文版(第5版)(顶级畅销书重磅升级全面采用最新 C++ 11标准) [美]Stanley B. Lippman( 斯坦利李普曼)  Josee Lajoie(约瑟拉乔伊 )  B ...

  4. C++11标准之右值引用(rvalue reference)

    1.右值引用引入的背景 临时对象的产生和拷贝所带来的效率折损,一直是C++所为人诟病的问题.但是C++标准允许编译器对于临时对象的产生具有完全的自由度,从而发展出了Copy Elision.RVO(包 ...

  5. 大数据 -- kafka学习笔记:知识点整理(部分转载)

    一 为什么需要消息系统 1.解耦 允许你独立的扩展或修改两边的处理过程,只要确保它们遵守同样的接口约束. 2.冗余 消息队列把数据进行持久化直到它们已经被完全处理,通过这一方式规避了数据丢失风险.许多 ...

  6. Python基础知识点整理(详细)

    Python知识点整理(详细) 输出函数 print()可以向屏幕打印内容,或者在打开指定文件后,向文件中输入内容 输入函数 input([prompt])[prompt] 为输入的提示字符.该函数返 ...

  7. Flutter教程- Dart语言规范-知识点整理

    Flutter教程- Dart语言知识点整理 Dart语言简介 Dart语言介绍 ① 注释的方式 ② 变量的声明 ③ 字符串的声明和使用 ④ 集合变量的声明 ⑤ 数字的处理 ⑥ 循环的格式 ⑦ 抛异常 ...

  8. vue前端面试题知识点整理

    vue前端面试题知识点整理 1. 说一下Vue的双向绑定数据的原理 vue 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫 ...

  9. CPP全面总结(涵盖C++11标准)

    OOP之类和对象 1. this指针的引入 每个成员函数都有一个额外的隐含的形参,这个参数就是this指针,它指向调用对象的地址.默认情况下,this的类型是指向类类型非常量版本的常量指针.可以表示成 ...

随机推荐

  1. myeclipse10.7导出war包时出错解决办法

    myeclipse10.7的版本破解后,导出war包时报“SECURITY ALERT: INTEGERITY CHECK ERROR”的错误. 选中项目->export->java ee ...

  2. shell脚本读取文件+读取命令行参数+读取标准输入+变量赋值+输出到文件

    读取url_list文件批量下载网页 url_list http://www.tianyancha.com/company/2412078287 http://www.4399.com/special ...

  3. C#连接EXCEL和ACCESS字符串2003及2007版

    97-2003版本 EXCEL Provider=Microsoft.Jet.OLEDB.4.0;Data Source=文件位置;ExtendedProperties=Excel 8.0;HDR=Y ...

  4. Python--(并发编程之线程Part2)

    GIL只能保证垃圾回收机制的安全,进程中的数据安全还是需要自定义锁 线程执行代码首先要抢到GIL全局锁,假设线程X首先抢到,以为要抢到自定义锁要执行代码,所以这个线程在执行代码的时候就很容抢到了自定义 ...

  5. 转载一篇pandas和,mysql

    http://pandas.pydata.org/pandas-docs/stable/comparison_with_sql.html#compare-with-sql-join http://bl ...

  6. Vue(6)- Vue-router进阶、单页面应用(SPA)带来的问题

    一.Vue-router进阶 回顾学过的vue-router,并参考官方文档学习嵌套路由等路由相关知识. 二.单页面应用(SPA)带来的问题 1.虽然单页面应用有优点,但是,如果后端不做服务器渲染(h ...

  7. CentOS7.1 KVM虚拟化之linux虚拟机安装(2)

    一.上传ISO文件到/data/iso下 这里使用CentOS-5.5-i386-bin-DVD.iso 二.安装CentOS5.5 CentOS7.1 安装KVM虚拟机默认磁盘格式为qcow2(推荐 ...

  8. Python高级教程-Map/Reduce

    Python中的map()和reduce() Python内建了map()和reduce()函数. map() map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每 ...

  9. 微信读书App来了 小伙伴们快去占榜吧

    微信读书App正式上线了,iOS版和Android版同时推出.届时将会出现像微信运动一样的霸榜小伙伴.资料显示,阅文集团成立于2014年1月,是腾讯文学和盛大文学联合成立的新公司.阅文集团成立后,会对 ...

  10. [cocos2dx笔记006]流格式日志

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/zdhsoft/article/details/36001945 在cocos2dx 2.2.2版本号 ...