C++之类的构造函数,不得不学明白的重点
一、认识构造函数
当创建一个类类型对象时,类通过一个或者几个特殊的成员函数来控制对象的初始化,这种函数就是构造函数。它的任务就是用来初始化类对象的成员的,所以当创建类对象或者类对象被创建就会调用构造函数。
构造函数的几个特点:
1.函数名和类名必须一样,没有返回值。
2.当没有显式的定义构造函数时,系统会自己生成默认的构造函数。
3.构造函数可以重载。
class Date
{
public:
Date()
{ }
Date(int day)
{
_year = ;
_month = ;
_day = day;
}
void print()
{
cout << _year << "-" << _month << "-" << _day << endl;
} private:
int _year=;
int _month;
int _day;
};
在上面的代码中,定义了一个简单的Date类类型,可以看到有显式的给出了构造函数,第一个是没有参数列表且函数不做任何事的,还有一个是有一个整型参数day的,就是当我传了一个day参数,则在函数内部把它的year和month初始化为1994和10。这样的两个构造函数就构成了重载,因为能够重载,所以在写构造函数的时候要保证只有一个缺省的构造函数。参数列表为空或者参数全缺省称为缺省构造函数。
当不传参的定义一个Date类型对象,会调用显式定义的缺省构造函数,在没有初始化列表的情况下采取类内初始化或默认初始化,上面的程序中,如果不传参,那么构建的对象的_year成员为1990,另外两个值为随机值。
牢记:
我们在没有显式的定义构造函数时,系统会自动生成一个默认构造函数。当我们定义了一些其他的构造函数时,这个类就将没有默认构造函数。所以当我们显式的定义了其他构造函数,最好把默认构造函数也显式的定义一遍。这样也有好处,就是系统生成的默认构造函数有可能执行错误的操作或者无法完成类成员的初始化(例如:有一个成员是类类型的对象且它没有缺省的构造函数)。
当我们定义的默认构造函数并不需要干什么事情,只是因为上面的情况才显式的定义它,那么此时的默认构造函数等同于系统生成的默认构造函数,那么我们可以这么定义:
Date() = default;
因为在新标准中,如果需要系统默认的行为,就可以通过在参数列表后加上=default来使编译器生成构造函数。
二、初始化列表
如下图所示,在冒号和花括号之间的代码部分称为构造函数的初始值列表,它的作用是给创建的对象的某些成员赋初值。这种是在构建对象的时候的初始化,是在对象创建成功之前完成的,和在函数体内赋值是不一样的,函数体内赋值是你的对象成员都已经创建好后对成员进行的赋值。

那么,可以看到,这种初始化并不是必须的。但是在以下几种情况时是必须进行初始化的:
1.成员是const类型。
2.成员是引用类型。
3.有一个成员是类类型的对象(且它没有缺省的构造函数)
class Time
{
public:
Time( )
{ } private:
int _hour;
};
class Date
{
public:
Date(int year=,int month=,int day=)
:_year(year), _month(month), _day(day), t()
{ }
void print()
{
cout << _year << "-" << _month << "-" << _day << endl;
}
private:
int _year=;
int _month;
int _day;
Time t;
};
解释:
1.对于const和引用类型,必须要进行初始化,所以他们必须在初始化列表中进行初始化。
2.当类类型成员有缺省的构造函数时,在创建对象的时候体统会默认调用,因为不用传参。当你的构造函数不是缺省的,如果不在初始化列表中进行调用构造函数,系统就无法知道怎么调用t的构造函数,那么就无法创建t了。
如上代码中,需要在参数列表中调用t的构造函数才不会出错。
成员初始化顺序:
在上面的初始列表中,每个成员只能出现一次,因为一个变量多次初始化是无意义的。
还有重要的一点,初始化列表的顺序并不限定初始化的执行顺序。成员的初始化顺序是与类中定义的顺序保持一致。可以看看下面的初始化列表:

GZ0(I)NL(]1@5Y2{I_7NJG.png)
在这里的意思是想要用1来初始化_month,再用_month初始化_year。但其实是_year被先初始化,而此时你的_month并没有初始化,所以,最后的结果是_year是一个随机值。
所以,最好让构造函数初始值的顺序与成员声明的顺序保持一致。
C++之类的构造函数,不得不学明白的重点的更多相关文章
- C++:构造函数2——拷贝构造函数
前言:拷贝构造函数是C++中的重点之一,在这里对其知识进行一个简单的总结. 一.什么是拷贝构造函数 在C++中,对于内置类型的变量来说,在其创建的过程中用同类型的另一个变量来初始化它是完全可以的,如 ...
- 关于peersim样例配置文件的超详细解读(新手勿喷)
相信很多兄弟一开始接触peersim,对配置文件还是有点不适应,我看了好久的样例的配置文件,一层层去找对应的文件的方法,终于好像悟懂了一点,记下来以后回顾. 贴上代码,一点点分析. 首先要说下所谓的配 ...
- Android 线程与消息 机制 15问15答
1.handler,looper,messagequeue三者之间的关系以及各自的角色? 答:MessageQueue就是存储消息的载体,Looper就是无限循环查找这个载体里是否还有消息.Handl ...
- JavaScript之面向对象学习一
1.通过Object构造函数和对象字面量来创建对象缺点:使用同一个接口创建很多的对象,会产生大量的重复代码.比如我需要创建人的对象,并且需要三类人,医生.工程师.老师,他们可以抽象出很多属性,比如姓名 ...
- Map实现之HashMap(结构及原理)(转)
java.util包中的集合类包含 Java 中某些最常用的类.最常用的集合类是 List 和 Map.List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构 ...
- Linux知识--初始linux
从今天开始陆续分享Linux的知识 因为服务器基本是Linux的 所以Linux不学明白 Shell命令不熟 会让你的办事效率大打折扣. 一.Linux文件系统 Linux文件系统是从Unix结构 ...
- okio:定义简短高效
欢迎关注公众号,第一时间获取最新文章: 本篇目录 一.前言 okio是大名鼎鼎的square公司开发出来的,其是okhttp的底层io操作库,既然已经有java原生的io库为什么还要自己费尽开发一套呢 ...
- 一段奇葩Javascript代码引发的思考
今天与一挚友加同事调试一段奇葩的javascript代码,在分析出结果后,让我萌生了写此篇文章的想法,如有不对之处望指正,也欢迎大家一起讨论.缩减后的js代码如下,你是否能准确说明他的输出值呢? fu ...
- ES6系列之箭头函数
本系列是在平时阅读.学习.实际项目中有关于es6中的新特性.用发的简单总结,目的是记录以备日后温习:本系列预计包含let/const.箭头函数.解构.常用新增方法.Symbol.Set&Map ...
随机推荐
- 第八章、Linux 磁盘与文件系统管理
认识 EXT2 文件系统 Linux最传统的磁盘文件系统(filesystem)使用的是EXT2这个啦!所以要了解文件系统就得要由认识EXT2开始! 而文件系统是创建在硬盘上面的,因此我们得了解硬盘的 ...
- Spring入门(3)-Spring命名空间与Bean作用域
Spring入门(3)-Spring命名空间与Bean作用域 这篇文章主要介绍Spring的命名空间和Bean作用域 0. 目录 Spring命名空间 Bean作用域 1. Spring命名空间 在前 ...
- ADUM1201在隔离RS232中的应用 【瓦特芯收藏】
ADUM1201在隔离RS232中的应用 引言: RS-232是PC机与工业通信中应用最广泛的一种串行接口.RS-232接口最初是由美国EIA(电子工业联合会)规定的用于计算机与终端设备之间通讯的一种 ...
- 利用hashtable和time函数加速Lisp程序
程序功能是从一个英文文本中得到单词表,再得到押韵词表.即输出可能这样开始: a ameoeba alba samba marimba... 这样结束: ...megahertz gigahertz j ...
- Objective-c setObject:forKey:和setValue:forKey:的区别
setObject:forKey: 是NSMutableDictionary类的方法 key参数类型可以是任意类型对象 ...
- CSS基础(02)
CSS 选择器 1.CSS3 选择器简介 在 CSS 中,选择器是一种模式,用于选择需要添加样式的元素. 语法: 下面中"CSS" 列指示该属性是在哪个 CSS 版本中定义的.(C ...
- wikioi 1154 能量项链
题目描述 Description 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的两颗珠子 ...
- LVM 创建分区扩展分区记录
LVM 原理 图片来自百度百科 测试环境centOS 7 LVM version: 2.02.115(2)-RHEL7 (2015-01-28) ...
- 图片攻击-BMP图片中注入恶意JS代码 <转载>
昨天看到一篇文章<hacking throung images>,里面介绍了如何在BMP格式的图片里注入JS代码,使得BMP图片既可以正常显示, 也可以运行其中的JS代码,觉得相当有趣. ...
- 很值得学习的java 画图板源码
很值得学习的java 画图板源码下载地址:http://download.csdn.net/source/2371150 package minidrawpad; import java.awt.*; ...