1. 程式人生 > >預設引數與初始化列表

預設引數與初始化列表

1.建構函式的預設引數在宣告時指定,(而不能只在定義建構函式時指定預設值)使得建立物件時,可以順序預設引數,使用預設引數初始化,例:

class Box{
    Box(int m = 10, int n= 20);//宣告
} 

    Box::Box(int m, int n) //實現
{
    int a = m;
    int b = n;
}

2.在一個類中定義了全部是預設引數的建構函式後,不能再定義過載建構函式,無參的建構函式是預設的,有參但都有預設引數的建構函式也是預設構造

3.預設引數,在C++中,只要是函式都可以有預設引數,預設引數是寫在函式聲明裡面的

初始化列表,是在建構函式裡的給之初始化,預設類內有整型物件 a.相當於,int a = 10

進一步的用法區別:
一、const和引用資料成員被初始化時,必須使用初始化列表,因為const成員只能被初始化,不能被賦值
const型別和引用型別,在建立時,必須進行初始化。若是把 ca = a; ra = this->a; 移到建構函式體內部,則無法通過編譯。也就是說,一旦進入建構函式體,初始化就已經完成了。

class Point
{
public:
Point():_x(0),_y(0){};
Point( int x, int y ):_x(x),_y(y){}
//Point(){ _x = 0; _y = 0;}錯誤
//Point( int x, int y ){ _x = 0; _y = 0; }錯誤
private: const int _x, _y; };

二、是從效率方面來說的,對於內建型別或複合型別,差異不會太大,但對於非內建資料型別,差異還是很明顯的

如再給Point類新增一個新的string型別的成員變數

class Point
{
const int _x, _y;
string _name;
};

建構函式內賦值進行初始化
Point( int x, int y, string name ){ _x = 0; _y = 0; _name = name; }

_name = name 這個表示式會呼叫string類的預設建構函式*一次,再呼叫Operator=函式進行賦值一次。所以需呼叫兩次函式:一次構造,一次賦值
用初始化列表進行初始化
Point( int x, int y, string name ):_x(x),_y(y), _name(name){}
_name會通過拷貝建構函式僅以一個函式呼叫的程式碼完成初始化
即使是一個很簡單的string型別,不必要的函式呼叫也會造成很高的代價。隨著類越來越大,越來越複雜,它們的建構函式也越來越大而複雜,那麼物件建立的代價也越來越高,所以一般情況下使用初始化列表進行初始化,不但可以滿足const和引用成員的初始化要求,還可以避免低效的初始化資料成員。

*預設建構函式是C++及其他一些面向物件程式設計語言中,物件的不需要引數即可呼叫的建構函式。物件生成時如果沒有顯式地呼叫建構函式,則預設建構函式會被自動呼叫。C++標準規定,如果建構函式沒有引數(nullary),或者建構函式的所有引數都有預設值(default value),都算作預設建構函式。[1]一個類只能有一個預設建構函式

成員型別是沒有預設建構函式的類。若沒有提供顯示初始化式,則編譯器隱式使用成員型別的預設建構函式,若類沒有預設建構函式,則編譯器嘗試使用預設建構函式將會失敗。

note:
初始化列表的成員初始化順序:
C++初始化類成員時,是按照宣告的順序初始化的,而不是按照出現在初始化列表中的順序

reference :
wikipedia預設建構函式

csdnblog 博文參考