初始化列表和構造函數初始化的區別


今天在做《面試筆試寶典》的時候,遇到了初始化列表和構造函數初始化區別的問題。之前只是知道有些情況必須用初始化列表,並且初始化列表的效率要高。但是要是說兩者的區別,還真是沒有探究過。網上搜了一些博客,對我很有幫助,但是感覺沒有講到自己異或的地方。所以自己實踐了一下。

首先,我們來把兩者的一般原型給出:

初始化列表方式:

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構造函數。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM