从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数
一、构造函数初始化列表
推荐在构造函数初始化列表中进行初始化
构造函数的执行分为两个阶段
初始化段
普通计算段
(一)、对象成员及其初始化
1 |
#include <iostream>
using namespace std; class Object class Container private: int main( |
从输出可以看出几点,一是构造对象之前,必须先构造对象的成员;二是对象成员构造的顺序与定义时的顺序有关,跟初始化列表顺序无关;三是构造的顺序和析构的顺序相反;四是如果对象成员对应的类没有默认构造函数,那对象成员也只能在初始化列表进行初始化。
(二)、const成员、引用成员的初始化
1 |
#include <iostream>
using namespace std; // const成员的初始化只能在构造函数初始化列表中进行 }; void DisplayKNum() int main( cout << obj1.TYPE_A << endl; return |
因为const 变量或者引用都得在定义的时候初始化,所以const 成员和引用成员必须在初始化列表中初始化。另外,可以使用定义枚举类型来得到类作用域共有的常量。
二、拷贝构造函数
(一)、拷贝构造函数
功能:使用一个已经存在的对象来初始化一个新的同一类型的对象
声明:只有一个参数并且参数为该类对象的引用 Test::Test(const Test &other) ;
如果类中没有定义拷贝构造函数,则系统自动生成一个缺省复制构造函数,作为该类的公有成员,所做的事情也是简单的成员复制
1 |
#ifndef _TEST_H_
#define _TEST_H_ class Test Test & ~Test(); |
1 |
#include
"Test.h" #include <iostream> using namespace std; // 不带参数的构造函数称为默认构造函数 Test::Test( Test::Test( Test::~Test() void Test::Display() Test &Test:: num_ = other.num_; |
1 |
#include
"Test.h" int main( return |
即调用了拷贝构造函数,destroy 的两个分别是t 和 t2。
(二)、拷贝构造函数调用的几种情况
当函数的形参是类的对象,调用函数时,进行形参与实参结合时使用。这时要在内存新建立一个局部对象,并把实参拷贝到新的对象中。理所当然也调用拷贝构造函数。
当函数的返回值是类对象,函数执行完成返回调用者时使用。理由也是要建立一个临时对象中,再返回调用者。为什么不直接用要返回的局部对象呢?因为局部对象在离开建立它的函数时就消亡了,不可能在返回调用函数后继续生存,所以在处理这种情况时,编译系统会在调用函数的表达式中创建一个无名临时对象,该临时对象的生存周期只在函数调用处的表达式中。所谓return 对象,实际上是调用拷贝构造函数把该对象的值拷入临时对象。如果返回的是变量,处理过程类似,只是不调用构造函数。
1 |
#include
"Test.h" #include <iostream> using namespace std; void TestFun( } void TestFun2( } Test TestFun3( const Test &TestFun4( int main( cout << return |
即在传参的时候调用了拷贝构造函数,函数返回时TestFun 的形参t 1生存期到了,在分割线输出之前销毁t1,最后destroy 的是 t。
将TestFun(t); 换成 TestFun2(t);
参数为引用,即没有调用拷贝构造函数。
将TestFun(t); 换成 t = TestFun3(t);
函数返回时会调用拷贝构造函数,接着调用赋值运算符,释放临时对象,最后释放t。如果没有用t 接收,则临时对象也会马上释放。
将TestFun(t); 换成 Test t2 = TestFun3(t);
函数返回调用拷贝构造函数,但没有再次调用拷贝构造函数,而且没有释放临时对象,可以理解成临时对象改名为t2 了。
将TestFun(t); 换成 Test& t2 = TestFun3(t);
函数返回时调用拷贝构造函数,因为t2 引用着临时对象,故没有马上释放。
将TestFun(t); 换成 Test t2 = TestFun4(t);
函数传参和返回都没有调用拷贝构造函数,初始化t2 时会调用拷贝构造函数。
将TestFun(t); 换成 const Test& t2 = TestFun4(t);
函数传参和返回都没有调用构造函数,t2 是引用故也不会调用拷贝构造函数。
最新文章
- C#生成二维码的方法
- json.stringfy()和json.parse()
- Linux安装snmp
- Android多媒体录制--MediaRecorder视频录制
- [LeetCode] Consecutive Numbers 连续的数字 --数据库知识(mysql)
- MyBatis之级联——鉴别器
- 【TOMCAT启动异常】The BASEDIR environment variable is not defined correctly
- Another Easy Problem fzu1753
- 2、公司部门的组成 - CEO之公司管理经验谈
- TS Eslint规则说明
- 【Unity3D技术文档翻译】第1.0篇 AssetBundles
- [bzoj4864][BeiJing 2017 Wc]神秘物质
- [转]Linux编译和安装boost库
- Debian如何永久添加静态路由
- Xilinx 常用模块汇总(verilog)【02】
- 三、git管理修改
- 【Alpha】第三次Scrum meeting
- WampServer在win10系统下安装的坑
- python Count类(转)
- [T-ARA][느낌 아니까][懂得那份感觉]