題目如下:問下列**的列印結果為0嗎?
#include #include using namespace std;
struct cls
cls()
};int main()
我當時是這樣想的,建構函式就是為物件分配記憶體的過程,其主要目的就是為了對私有變數進行初始化,所以我就想乙個物件不能呼叫
兩次建構函式,即使這兩種建構函式是過載過的,像題目中的
cls()
因為不太確定,回來查了一下,原來我之前的理解雖然沾了點邊,但是還是沒有想到點子上去。
首先在物件沒有動態資源的時候,物件的記憶體分配在建構函式之前,此時建構函式的主要任務就是初始化物件的private成員,記憶體分配在建構函式執行之前,所以建構函式裡呼叫另一種形式的建構函式(帶引數的建構函式),其實編譯器又生成了乙個臨時物件,這個臨時物件的
private成員通過其引數得到初始化,但是原來的物件的資料成員並沒有初始化,是個隨機值。看了下面的測試**,你就會明白一切// 構造函式呼叫建構函式的問題.cpp : 定義控制台應用程式的入口點。
//#include "stdafx.h"
#include using namespace std;
class widget
{public:
widget(int n)
{m_idata = n;
cout<<"有引數的建構函式中的this:"<
很明顯在兩個建構函式中分別是兩個物件,而且原物件的private成員是個隨機值,所以我們要盡量避免在建構函式中呼叫另一形式的建構函式,那麼構造函式呼叫自身就可以了嗎?當然不行,這樣會陷入無窮遞迴,有興趣的可以實驗一下
如果實在避免不了構造函式呼叫另一形勢的建構函式時怎麼辦?網上查了下,可以用下面的方法解決,new (this)cls(8888),
這種方式是在原來的物件上呼叫另一形勢的建構函式,不會生成新的臨時物件。
下面是演示**:
// 構造函式呼叫建構函式的問題.cpp : 定義控制台應用程式的入口點。
//#include "stdafx.h"
#include using namespace std;
class widget
{public:
widget(int n)
{m_idata = n;
cout<<"有引數的建構函式中的this:"<
不帶引數的建構函式的實現裡去呼叫帶引數的建構函式時,並沒有完成物件內部的函式呼叫,而是優先選擇了通過帶引數建構函式又構造出了乙個新的臨時物件,所以盡量避免在建構函式中呼叫建構函式,不管是建構函式自身還是過載過的建構函式
C 中構造函式呼叫建構函式
include include using namespace std struct cls cls int main 列印結果是不定的,不一定為0 奇怪的地方在於建構函式中呼叫了自己的另乙個建構函式 我們知道,當定義乙個物件時,會按順序做2件事情 1 分配好記憶體 非靜態資料成員是未初始化的 2 ...
C 中構造函式呼叫建構函式
include stdlib.h include iostream using namespace std struct clscls int main 列印結果是不定的,不一定為0 奇怪的地方在於建構函式中呼叫了自己的另乙個建構函式 我們知道,當定義乙個物件時,會按順序做2件事情 1 分配好記憶體...
c 中構造函式呼叫建構函式
c 中建構函式完成的工作分兩步 1 分配空間 2 初始化空間 構造函式呼叫建構函式。class a a int a private int a 這樣會導致,a 中先分配了空間,然後呼叫a 0 又建立了乙個臨時物件,然後初始化為0,而原物件則沒有初始化。這種問題在類中有指標需要分配空間時會導致災難。從...