初始化列表和构造函数初始化的区别

今天在做《面试笔试宝典》的时候,遇到了初始化列表和构造函数初始化区别的问题。之前只是知道有些情况必须用初始化列表,并且初始化列表的效率要高。但是要是说两者的区别,还真是没有探究过。网上搜了一些博客,对我很有帮助,但是感觉没有讲到自己异或的地方。所以自己实践了一下。

首先,我们来把两者的一般原型给出:

初始化列表方式:

Object::Object(itn _x,int _y):x(_x),y(_y)
{
}

构造函数初始化:

Object::Object(int _x,int _y)
{
      x = _x;
      y = _y;        
}  

初始化列表和构造函数初始化(赋值)的方式对于内置类型的成员(如int等)来说,其实没有什么区别,其性能和结果往往一样。

但是,对于非内置类型的成员(类类型)来说,是有区别的。

我们举个栗子:

这是CMember类

#ifndef _CMEMBER_H_
#define _CMEMBER_H_

#include <iostream>
using namespace std;

class CMember
{
public:
    CMember()
    {
        cout << "CMember constructor 1" << endl;
        cmember = 0;
    }
    CMember(CMember& obj)
    {
        cout << "CMember copy constructor" << endl;
    }
    CMember(int _cmember)
    {
        cout << "CMember constructor 2" << endl;
        cmember = _cmember;
    }

    CMember& operator =(CMember& obj)
    {
        cout << "CMember =" << endl;
        return *this;
    }

    int cmember;
};

#endif _CMEMBER_H_

这是MClass类

#ifndef _MCLASS_H_
#define _MCLASS_H_

#include <iostream>
using namespace std;

#include "CMember.h"

class MClass
{
    //MClass(CMember& _cm) :cm(_cm)
    //{
    //    //cm = _cm;
    //}
public:
    MClass(CMember& _cm)   //注意这里我们用的是引用,如果没有用引用,则会多一次copy构造函数的调用
    {
        cm = _cm;
    }

    CMember cm;

};

#endif _MCLASS_H_

 

因为编译器总是确保所有成员对象在构造函数体执行之前初始化,所以类类型的数据成员对象,在进入构造函数体之前已经完成构造。例子中编译的代码将调用CMember:: CMember()来初始化cm(这里调用一次CMember构造函数),这在控制到达赋值语句前完成。接下来有调用一个赋值运算符函数。结果是调用了两个Cstring函数(构造函数和赋值操作符)。

我们测试一下:

#include <iostream>
using namespace std;

#include "CMember.h"
#include "MClass.h"

void main()
{
    CMember c1(1);
    MClass m1(c1);

    getchar();
    
    
}

输出如下:

 

 

下面我们试一下,初始化列表方式。

MClass(CMember& _cm) :cm(_cm)
    {
        
    }

输出:

只调用一次copy构造函数。

 

posted @ 2017-03-25 12:08  ren_zhg1992  阅读(3878)  评论(0编辑  收藏