C++学习 对象模型之细谈成员初始化列表

直接上代码

上面红色框起来的部分就是类成员初始化列表,成员初始化列表一般用在类的构造函数中,包括拷贝构造函数。对于这种用法,作为C++程序员一点都不陌生。下面从几个疑惑开始讲解,成员初始化列表:

1.什么时候必须要使用初始化列表

(1)初始化成员有引用

以上代码编译器会报错,编译器不允许这样初始化,至于为什么不允许,后面再探讨,只能按照一下方式来初始化引用成员数据

这样编译器就不会报错了

(2)初始化const类型成员

这样初始化const 类型成员编译器会报错,至于编译器为什么会允许这样做,还没明白。按照以下做法就不会报错

 

(3)类继承于一个父类,且父类含有有参数的构造函数

(3)含有类成员变量,且类成员的构造函数有参数

 

2.为什么要使用成员初始化列表,答案是为了提高程序的效率

既然发明了这个语法,一定有一定的道理,且一定有利于程序的运行。以下代码可以非常清晰的说明:

class A {
public:
    int m_a;
    int m_b;
    A(){
        cout << "A 的构造函数" << endl;
    }
    A(int tmp):m_a(tmp),m_b(tmp) {
        cout << "A 的拷贝构造函数" << endl;
    }
    ~A() {
        cout << "A 的析构函数" << endl;
    }

};
class B  {
public:
    int tt_a;
    int tt_b;
    A m_aobj;
    B(int a, int b) : tt_a(a), tt_b(b) {
        m_aobj = a;

        cout << "B 的构造函数" << endl;
    }
    ~B() {
        cout << "B 的析构函数" << endl;
    }

};

int main()
{
    //A a_obj1(10,20);
    B b(10, 20);
    std::cout << "Hello World!\n";
    return 0;
}

这时候m_aobj 成员我们没有用初始化列表来初始化,运行结果为

 

如果m_aobj换成在初始化列表中初始化,如下代码

class B  {
public:
    int tt_a;
    int tt_b;
    A m_aobj;
    B(int a, int b) :m_aobj(a), tt_a(a), tt_b(b) {
        //m_aobj = a;

        cout << "B 的构造函数" << endl;
    }
    ~B() {
        cout << "B 的析构函数" << endl;
    }

};

运行结果就变成

 

很明显的看到后者少调用了一次A的构造函数和一次析构函数。因为前者编译器会生成一个临时对象。由此说明成员初始化列表优化程序运行效率。

 

(3)使用成员初始化列表需要注意哪些细节

(1)成员初始化列表会被编译器转换为代码并被放在用户代码之前。‘

(2)成员的初始化并不是按照初始化列表的顺序来的,而是按照成员在类的定义顺序来初始化

class A {
public:
    int m_a;
    int m_b;
    A(int a):m_a(a){
        cout << "A 的构造函数" << endl;
    }
    ~A() {
        cout << "A 的析构函数" << endl;
    }

};
class B  {
public:
    int tt_a;
    int tt_b;
    B(int a, int b) : tt_a(a), tt_b(b) {
        //m_aobj = a;

        cout << "B 的构造函数" << endl;
    }
    ~B() {
        cout << "B 的析构函数" << endl;
    }

};

class C {
public:
    A aa;
    B bb;
    C(int a) :bb(a,a), aa(a) {
        cout << "C 的构造函数" << endl;
    }

};

int main()
{
    //A a_obj1(10,20);
    C c(10);
    std::cout << "Hello World!\n";
    return 0;
}

这里我们的初始化列表顺序是 B A,定义顺序是A B。运行结果如下

显然是按照定义的顺序来初始化的,而不是初始化列表顺序。

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值