初始化列表对于普通的内置类型(int,float,char,bool 等),以及指针类型,是没有什么太大意义的;用初始化列表还是构造函数内部赋值都是一样的;
1 初始化列表是什么?
构造函数: ClassA():a(),b(),c(){}; 使用初始化列表
ClassA(){ a = 0; b = 0;c = 0};未使用初始化列表
2 看一个程序:
#include "stdafx.h"
#include <iostream>
using namespace std;
int main()
{
ct1* A = new ct1();
return 0;
}
我们把ct1的构造函数添加上初始化列表:
再看看打印:
我想说什么呢,就是你用不用初始化列表;其实没区别;为什么没区别,因为类ct1的成员变量是内置类型和 普通指针;“类”类型的指针也是指针;
下边说的是重点。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
下边我们在看看第二种情况:我们先不写初始化列表;只把成员变量中函数指针改成‘类’类型变量
#include "stdafx.h" #include <iostream> #include <memory> using namespace std; int main() { ct1* A = new ct1(); return 0; }
看打印:
这说明如果你的类成员变量是一个 类类型,那在进入构造函数前,这个类类型变量会先走一遍默认构造函数;
我们把初始化列表放开,打印亦如此;
ct1::ct1():a(0),bflag(0), memsub() { printf("create ct1\n"); }
那这里是不是就意味着,如果你不使用初始化列表,而改为构造函数内部赋值,这个memsub 的成员变量不仅会调用一次普通构造,还会调用一个赋值构造?我们来验证一下;
我这里为了保证memsub有一个从外边来的值,所以写了个非默认类型构造函数;我们看打印的时候只看main的第15行就行:
是不是除了本身的第一次构造,还调用了一次赋值构造。。。。至于为什么还有一次拷贝构造(是因为赋值构造的return会触发一次临时变量的生成,就会有一次拷贝构造的触发,就是上图黄色的圈那里;这里赋值构造之所以会在return时候再次调用拷贝构造是因为我写的赋值构造的返回值是类类型,如果我的赋值构造的返回类型是一个引用,他就不会触发最后一行的拷贝构造了。也就是
MyClass MyClass::operator=(const MyClass& A) 和 MyClass& MyClass::operator=(const MyClass& A)的区别,严格意义上将赋值构造返回引用 才是对的)
下面我们来分析下上图打印的结果对应的代码流程:
下面为了让你更直观的感受到初始化列表的力量,我们来看看下边的程序,只把上图的代码用初始化列表来完成:
我们来分析下中间那两行打印是怎么来的;【我这里为什么要给ct1的构造函数传csub的引用是因为,这样少一次sub对象的拷贝构造;因为要是不传引用,函数传值传的是X的一份拷贝】
所以对于包含 类 类型的成员的构造函数,使用初始化列表比不使用,会少一次拷贝,赋值,构造;或者你说少一次赋值构造也是对的,因为赋值构造引起了另一次的拷贝构造;
其他三种场景,也是初始化列表的用武之地: