#include
<
stdlib.h
>
#include
<
iostream
>
using
namespace
std;
struct
clscls()
};int
main()
列印結果是不定的,不一定為0
**奇怪的地方在於建構函式中呼叫了自己的另乙個建構函式
我們知道,當定義乙個物件時,會按順序做2件事情:
1)分配好記憶體(非靜態資料成員是未初始化的)
2)呼叫建構函式(建構函式的本意就是初始化非靜態資料成員)
顯然上面**中,cls obj;這裡已經為obj分配了記憶體,然後呼叫預設建構函式,但是預設建構函式還未執行完,卻呼叫了另乙個建構函式,這樣相當於產生了乙個匿名的臨時cls物件,它呼叫cls(int)建構函式,將這個匿名臨時物件自己的資料成員m_i初始化為0;但是obj的資料成員並沒有得到初始化。於是obj的m_i是未初始化的,因此其值也是不確定的
從這裡,我們歸納如下:
1)在c++裡,由於建構函式允許有預設引數,使得這種構造函式呼叫建構函式來重用**的需求大為減少
2)如果僅僅為了乙個建構函式重用另乙個建構函式的**,那麼完全可以把建構函式中的公共部分抽取出來定義乙個成員函式(推薦為private),然後在每個需要這個**的建構函式中呼叫該函式即可
3)偶爾我們還是希望在類的建構函式裡呼叫另乙個建構函式,可以按下面方式做:
在建構函式裡呼叫另乙個建構函式的關鍵是讓第二個建構函式在第一次分配好的記憶體上執行,而不是分配新的記憶體,這個可以用標準庫的placement new做到:
先看看標準庫中placement new的定義
inline
void
*__cdecl
operator
new(size_t,
void
*_p)
可見沒有分配新的記憶體。
正確的方式:
struct
clscls()};
另: 若構造函式呼叫自身,則會出現無限遞迴呼叫,是不允許的
C 中構造函式呼叫建構函式
include include using namespace std struct cls cls int main 列印結果是不定的,不一定為0 奇怪的地方在於建構函式中呼叫了自己的另乙個建構函式 我們知道,當定義乙個物件時,會按順序做2件事情 1 分配好記憶體 非靜態資料成員是未初始化的 2 ...
c 中構造函式呼叫建構函式
c 中建構函式完成的工作分兩步 1 分配空間 2 初始化空間 構造函式呼叫建構函式。class a a int a private int a 這樣會導致,a 中先分配了空間,然後呼叫a 0 又建立了乙個臨時物件,然後初始化為0,而原物件則沒有初始化。這種問題在類中有指標需要分配空間時會導致災難。從...
C 中構造函式呼叫建構函式
include include using namespace std struct cls cls int main 列印結果是不定的,不一定為0 奇怪的地方在於建構函式中呼叫了自己的另乙個建構函式 我們知道,當定義乙個物件時,會按順序做2件事情 1 分配好記憶體 非靜態資料成員是未初始化的 2 ...