成员初始化列表细说

一:何时必须使用初始化列表

#include <iostream>
using namespace std;

class Base
{
public:
    Base(int i)
    {
        cout<<"调用了Base(int i)"<<endl;
    }
    ~Base()
    {
        cout<<"调用了~Base()"<<endl;
    }
};

class X
{
public:
    X(int i)
    {
        cout<<"调用了X(int i)"<<endl;     
    }
    ~X()
    {
        cout<<"调用了~X()"<<endl;
    }
};

class A:public Base
{
public:
    const int m_i;
    int &b; 
    X x;
public:
    A(int i=0):m_i(i),b(i),Base(i),x(10) //必须用初始化列表的方式初始化这4中类型
    {
        cout<<"调用了 A(int i=0):m_i(i),b(i),Base(i),x(10)"<<endl; 
    }
    ~A()
    {
        cout<<"调用了 ~A()"<<endl; 
    }
};


int main(void)
{
    A obj(10);
    return 0;
}
//总结:必须用初始化列表的4种情形
/*
 a:成员有引用
 b:成员是const类型
 c:类中的成员变量有类类型,并且这个类类型没有默认构造函数(也就是它的构造函数是带有参数的)
 d:类继承了某个类,并且这个类(父类)的构造函数是带参数的
 */

二:使用初始化列表的优势

除了上述的必须使用初始化列表的情形的化,其它情况下使用初始化列表的方式主要是为了提高程序的运行效率,,通过一个例子来看看使用初始化列表和不使用初始化列表的情况吧。

#include <iostream>
#include<stdio.h>
using namespace std;

class X
{
public:
    X(int i=0):m_i(i)
    {
        printf("this = %p",this);
        cout<<"调用了X(int i=0):m_i(i)"<<endl;
    }
    ~X()
    {
        printf("this = %p",this);
        cout<<"调用了 ~X()"<<endl;
    }

    X(const X& p)
    {
        printf("this = %p",this); 
        cout<<"调用了  X(const X& p)"<<endl;
    }

    X& operator=(const X&)
    {
        printf("this = %p",this); 
        cout<<"调用了X& operator=(const X&)"<<endl;
    }
public:
    int m_i;
};

class T
{
public:
    X obj;
    int m_i;
public:
    T(int tmpobj)
    {
        obj=100;
        m_i=10;
        cout<<"调用了T(int tmpobj)"<<endl;  
    }

    ~T()
    {
      cout<<"调用了 ~T()"<<endl;  
    }
};

int main(void)
{
    T(90);
    return 0;
}

执行结果:
在这里插入图片描述
再来看:

#include <iostream>
#include<stdio.h>
using namespace std;

class X
{
public:
    X(int i=0):m_i(i)
    {
        printf("this = %p",this);
        cout<<"调用了X(int i=0):m_i(i)"<<endl;
    }
    ~X()
    {
        printf("this = %p",this);
        cout<<"调用了 ~X()"<<endl;
    }

    X(const X& p)
    {
        printf("this = %p",this); 
        cout<<"调用了  X(const X& p)"<<endl;
    }

    X& operator=(const X&)
    {
        printf("this = %p",this); 
        cout<<"调用了X& operator=(const X&)"<<endl;
    }
public:
    int m_i;
};

class T
{
public:
    X obj;
    int m_i;
public:
    T(int tmpobj):obj(tmpobj)
    {
       // obj=100;
        m_i=10;
        cout<<"调用了T(int tmpobj)"<<endl;  
    }

    ~T()
    {
      cout<<"调用了 ~T()"<<endl;  
    }
};

int main(void)
{
    T(90);
    return 0;
}

在这里插入图片描述
发现少了一些步骤了吧?

由于在不使用初始化列表的情况下,编译器执行程序时,还会生成临时对象,,,,所以来说还是使用初始化列表有优势。

但是这种优势对于一般的内置类型,比如int等等就不太明显,对于类类型来说,明显可就大了。

三:成员初始化列表细节探秘
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值