C++使用初始化列表的意义在哪?

初始化列表对于普通的内置类型(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的一份拷贝】

 所以对于包含 类 类型的成员的构造函数,使用初始化列表比不使用,会少一次拷贝,赋值,构造;或者你说少一次赋值构造也是对的,因为赋值构造引起了另一次的拷贝构造;


 

其他三种场景,也是初始化列表的用武之地:

1.常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
2.引用类型,引用必须在定义的时候初始化,并且不能重新赋值,所以也要写在初始化列表里面
3. 没有默认构造函数的类类型,因为使用初始化列表可以不必调用默认构造函数来初始化,而是直接调用拷贝构造函数初始化

posted on 2022-05-19 00:12  邗影  阅读(300)  评论(0编辑  收藏  举报

导航