Posted on 2007-08-30 10:28
寶杉 閱讀(197)
評論(0) 編輯 收藏 引用 所屬分類:
C++
析構函數
構造函數初始化表:構造函數特殊的初始化方式“初始化表達式表”(簡稱初始化表)。
初始化表位于函數參數表之后,卻在函數體 {} 之前。這說明該表里的初始化工作發生在函數體內的任何代碼被執行之前。
規則
u 如果類存在繼承關系,派生類必須在其初始化表里調用基類的構造函數。
u 類的const常量只能在初始化表里被初始化,因為它不能在函數體內用賦值的方式來初始化。
u 類的數據成員的初始化可以采用初始化表或函數體內賦值兩種方式,這兩種方式的效率不完全相同。
效率
1 內部成員:
初始化表和函數體內賦值都可以,但效率不完全相同,但后者更為清晰直觀。
例子:
class F
{
public:
F(int x, int y); // 構造函數
private:
int m_x, m_y;
int m_i, m_j;
}
F::F(int x, int y)
: m_x(x), m_y(y)
{
m_i = 0;
m_j = 0;
}
|
F::F(int x, int y)
{
m_x = x;
m_y = y;
m_i = 0;
m_j = 0;
}
|
示例9-2(c) 數據成員在初始化表中被初始化 示例9-2(d) 數據成員在函數體內被初始化
兩種方式效率區別不大。
2 非內部成員:
只能用初始化表,提高效率。
例子:
class A
{…
A(void); // 無參數構造函數
A(const A &other); // 拷貝構造函數
A & operate =( const A &other); // 賦值函數
};
class B
{
public:
B(const A &a); // B的構造函數
private:
A m_a; // 成員對象
};
比較與分析:
B::B(const A &a)
: m_a(a)
{
…
}
|
B::B(const A &a)
{
m_a = a;
…
}
|
1 B類構造函數的初始化里,調用了A類的拷貝構造函數。
2 B類構造初始化里,隱藏了以下幾個步驟:
先創建了a對象,調用了A類的無參數構造函數;
把a賦值給m_a,調用了A類的賦值函數;
深入探討:
構造和析構的次序?
構造從最深處的基類開始的,先一層層調用基類的構造函數,然后調用成員對象的構造函數。
而析構函數嚴格按照構造函數相反的次序執行,該次序唯一,以便讓編譯器自動執行析構函數。
特別之處是,成員對象初始化次序不受構造函數初始化表次序影響,由在類中聲明的次序決定。而類聲明是唯一的,構造函數卻可能有多個,所以有多個不同次序函數初始化表。如果按照構造函數的次序構造,那么解析函數不能得到唯一的逆序。