C++构造函数初始化列表

一直不怎么在意构造函数的初始化列表,从觉得放在列表里和放在构造函数体里面一样,实际上 二者还是有差别的。

构造函数初始化列表以一个冒号开始,接着用逗号隔开各个成员,每个成员后面跟着一个放在小括号内的初始化式。例如下面的初始化列表

class Base {
    public:
        Base(int a, double b) :i_val(a), d_val(b)//(1)这个就是有初始化列表的构造函数 
        {cout << "Base(int a, double b)" << endl;}
        Base() {i_val = 0; d_val = 0.0; cout << "Base()" << endl;  }//(2)没有初始化列表
    private:
        int i_val;
        double d_val;
}
实际上,构造函数有两个执行阶段:(1)初始化阶段 (2)普通计算阶段。计算阶段由构造函数体中的所有语句组成。不管成员是否在初始化列表中显示初始化,类类型的数据成员总是在初始化阶段初始化。初始化阶段发生在计算阶段开始之前。对于内置类型(比如说int)或者指针,那么在列表中和函数体中初始化是没有性能的差别.但是对于用户自定义类型,性能还是有差别的,因为构造函数会在进入函数体之前,对成员变量调用默认构造函数进行初始化。示例如下:

#include <iostream>
using namespace std;

class Base {
    public:
        Base() {cout << "Base()" << endl;}
        Base(int j) {cout << j << endl;}
};
class Derive : public Base {
    public:
        //Derive(): b_val(2) { cout << "Derive()" << endl;} //(1)
        Derive() { b_val = 2; cout << "Derive()" << endl;} //(2)
    private:
        Base b_val;
};
int main()
{
    Base b;
    Derive d;
}
把构造函数(1)注释掉, 保留(2),输出为

Base()   //b的构造函数
Base()    //Derive继承Base 调用Base构造函数生成父类
Base()    //初始化列表中初始化b_val 调用的默认构造函数 
2         //在函数体中调用Base的一个构造函数
Derive()  //d的构造函数
把构造函数(2)注释掉, 保留(1),输出为

Base()    //b的构造函数
Base()    //Derive继承Base 调用Base构造函数生成父类
2          //在函数体中调用Base的一个构造函数
Derive()  //d的构造函数
可以看到,b_val放在初始化列表中,可以少调用一次其默认构造函数(Base()),因为在进入函数体之前,已经初始化了b_val,然后在函数体里面又初始化了一次。

还有三种情况,成员变量必须放在初始化列表中进行初始化

1,没有默认构造函数的类类型成员。初始化列表会自动调用默认的构造函数,如果没有默认构造函数,编译出错

2,const 成员                                   const 对象或引用只能初始化,不能被赋值,所以唯一的合法机会就是放在初始化列表中进行初始化。

3,引用类型成员                            同2







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值