c當建構函式失敗時建構函式內部怎麼處理

2021-06-25 14:47:34 字數 4854 閱讀 7265

1樓:w別y雲j間

1、建構函式想通知外部自己構造失敗,只有拋異常這一個途徑(沒有返回值);

2、 如果不拋異常,那麼建構函式執行完畢,從語言層面上編譯器認為該物件是正確構造了的,其實構造沒有按預想的進行,所以需要用狀態變數、建構函式引用引數就可以讓外界可以知道構造失敗了。

3.、如果拋異常標識構造失敗,那麼,所有已經構造好的基類物件和資料成員會按照構造逆序逐個進行析構(基礎資料型別除外,因為它們析構就是什麼都不做)。這裡有一點要注意,如果發生了動態記憶體分配,那需要在拋異常前手動釋放記憶體,否則會有記憶體洩漏。

建構函式 ,是一種特殊的方法。主要用來在建立物件時初始化物件, 即為物件成員變數賦初始值,總與new運算子一起使用在建立物件的語句中。特別的一個類可以有多個建構函式 ,可根據其引數個數的不同或引數型別的不同來區分它們 即建構函式的過載。

2樓:匿名使用者

你沒有明確什麼叫「建構函式失敗」。我的理解是:建構函式中某一個執行過程沒有得到你期望的結果。

如果我的理解是你想表達的,那麼建構函式內部的處理是這樣:

1. 建構函式想通知外部自己構造失敗,只有拋異常這一個途徑(沒有返回值);

2. 如果你不拋異常,那麼建構函式執行完畢,從語言層面上編譯器認為該物件是正確構造了的,只有你知道其實構造沒有按預想的進行,所以你需要用狀態變數、建構函式引用引數或什麼其他玩意兒讓外界可以知道構造失敗了。

3. 如果你拋異常標識構造失敗,那麼,所有已經構造好的基類物件和資料成員會按照構造逆序逐個進行析構(基礎資料型別除外,因為它們析構就是什麼都不做)。這裡有一點要注意,如果發生了動態記憶體分配,那需要在拋異常前手動釋放記憶體,否則會有記憶體洩漏。

齊活,不知道能不能回答你的問題。

3樓:匿名使用者

啊。沒試過建構函式失敗的情況。。除非你記憶體空間沒有了。。

c++建構函式丟擲異常怎麼處理

4樓:好程式設計師

1、標準c++中定義建構函式是一個物件構建自己,分配所需資源的地 方,一旦建構函式執行完畢,則表明這個物件已經誕生了,有自己的行為和內部的執行狀態,之後還有物件的消亡過程(解構函式的執行)。可誰能保證物件的構造 過程一定能成功呢?說不定系統當前的某個資源不夠,導致物件不能完全構建好自己(人都有畸形兒,更何況別的呢?

朋友們!是吧!),因此通過什麼方法來表明 物件的構造失敗了呢?

c++程式設計師朋友們知道,c++中的建構函式是沒有返回值的,所以不少關於c++程式設計方面的書上得出結論:「因為建構函式沒有返回 值,所以通知物件的構造失敗的唯一方法那就是在建構函式中丟擲異常」。主人公阿愚非常不同意這種說法,誰說的,便不信邪!

雖然c++標準規定建構函式是沒 有返回值,可我們知道每個函式實際上都會有一個返回值的,這個值被儲存在eax暫存器中,因此實際上是有辦法通過程式設計來實現建構函式返回一個值給上層的對 象建立者。當然即便是建構函式真的不能有返回值,我們也可以通過一個指標型別或引用型別的出參來獲知物件的構造過程的狀態。示例如下:

class mytest_base

protected:

};void main()

程式執行的結果是:

物件構建失敗

是啊!上面我們不也得到了物件構造的成功與否的資訊了嗎?可大家有沒有覺得這當中有點問題?

建議在此停留片刻,仔細想想它會有什麼問題?ok!也許大家都知道了問題的所在,來驗證一下吧!

class mytest_base

virtual ~ mytest_base ()

protected:

};void main()

程式執行的結果是:

物件構建失敗

銷燬一個mytest_base型別的物件

沒錯,物件的解構函式被執行了,這與c++標準中所規定的物件導向的一些特性是有衝突的。一個物件都沒有完成自己的構造,又何來析構!好比一個 夭折的畸形兒還沒有出生,又何來死之言。

因此這種方法是行不通的。那怎麼辦?那就是上面那個結論中的後一句話是對的,通知物件的構造失敗的唯一方法那就是 在建構函式中丟擲異常,但原因卻不是由於建構函式沒有返回值而造成的。

恰恰相反,c++標準中規定建構函式沒有返回值正是由於擔心很容易與物件導向的一些 特性相沖突,因此乾脆來個規定,建構函式不能有返回值

2、建構函式中丟擲異常將導致物件的解構函式不被執行。如果沒有c++的異常處理機制鼎立支援,c++中的面向 物件特性都無法真正實現起來,c++標準總不能規定所有的物件都必須成功構造吧!這也太理想化了,也許只有等到共產主義社會實現的那一天(cpu可以隨便 拿,記憶體可以隨便拿,所有的資源都是你的!

)才說不定有可能·····,所以說c++的異常處理和麵向物件確實是誰也離不開誰。當然示例還是要看一下,如 下:

class mytest_base

virtual ~ mytest_base ()

void func() throw()

void other() {}

protected:

string m_name;

};void main()

catch(std::exception e)

catch(...)

}程式的執行結果將會驗證:「建構函式中丟擲異常將導致物件的解構函式不被執行」

3、是不是到此,關於建構函式中丟擲異常的處理的有關討論就能結束了呢?非也!非也!主人公阿愚還有進一步的故事需要講述!來看一個更復雜一點的例子吧!如下:

class mytest_base

virtual ~ mytest_base ()

void func() throw()

void other() {}

protected:

string m_name;

};class mytest_parts

virtual ~ mytest_parts ()

};class mytest_derive : public mytest_base

virtual ~ mytest_derive ()

protected:

mytest_parts m_component;

};void main()

catch(std::exception e)

catch(...)

}程式執行的結果是:

構造一個mytest_base型別的物件,物件名為:obj1

構造一個mytest_parts型別的物件

銷燬一個mytest_parts型別的物件

銷燬一個mytest_base型別的物件,物件名為:obj1

在mytest_derive物件的建構函式中丟擲了一個異常!

上面這個例子中,mytest_derive從mytest_base繼承,同時mytest_derive還有一個mytest_parts 型別的成員變數。現在mytest_derive構造的時候,是在父類mytest_base已構造完畢和mytest_parts型別的成員變數 m_component也已構造完畢之後,再丟擲了一個異常,這種情況稱為物件的部分構造。是的,這種情況很常見,物件總是由不斷的繼承或不斷的聚合而 來,物件的構造過程實際上是這些所有的子物件按規定順序的構造過程,其中這些過程中的任何一個子物件在構造時發生異常,物件都不能說自己完成了全部的構造 過程,因此這裡就有一個棘手的問題,當發生物件的部分構造時,物件將析構嗎?

如果時,又將如何析構呢?

從執行結果可以得出如下結論:

(1) 物件的部分構造是很常見的,異常的發生點也完全是隨機的,程式設計師要謹慎處理這種情況;

(2) 當物件發生部分構造時,已經構造完畢的子物件將會逆序地被析構(即異常發生點前面的物件);而還沒有開始構建的子物件將不會被構造了(即異常發生點後面的 物件),當然它也就沒有析構過程了;還有正在構建的子物件和物件自己本身將停止繼續構建(即出現異常的物件),並且它的析構是不會被執行的。

建構函式中丟擲異常時概括性總結

(1) c++中通知物件構造失敗的唯一方法那就是在建構函式中丟擲異常;

(2) 建構函式中丟擲異常將導致物件的解構函式不被執行;

(3) 當物件發生部分構造時,已經構造完畢的子物件將會逆序地被析構;

(4) 哈哈^-^,其是還是那句話, 「c++的異常處理不會破壞任何一條物件導向的特性!」

c++中為什麼基類中只有帶引數的建構函式時,派生類中一定要顯示定義建構函式,並寫出基類的建構函式及引數

5樓:匿名使用者

因為建立派

抄生類物件時要呼叫基類的bai建構函式,當基類du沒有定義構函式時就調

zhi用預設dao無引數的建構函式。當只定義了有參的建構函式時就呼叫有參的建構函式,所以當派生類沒有給基類傳遞引數時就會出現錯誤。解決方法:

可以在基類中過載一個無參建構函式,或者給有參建構函式的引數設定預設值。

6樓:匿名使用者

當你定義一個派生類抄的物件時首

襲先呼叫的是基類的

建構函式,如基類的建構函式是帶參的 在派生類建構函式的後面會有基類的建構函式的傳參 否則就會報錯 指的是呼叫基類中你定義的這個建構函式而不是預設的無參建構函式

c++中有多個建構函式的類,在使用預設建構函式的例項建立後,再呼叫類方法時出錯。

7樓:匿名使用者

這個問題bai是函式預設值的問du題造成的。

a (int w=15) 其實相當於

zhi兩dao個宣告 即使用預設值的回a()和不使答用預設值的a(int)。

你用的編譯器版本比較老了吧,第一個會直接提示一個錯誤而不是警告,很明顯的這個也是函式過載時常見的錯誤之一。記住有預設值的函式簽名包括數個(預設值個數+1)不同的呼叫簽名,如果有衝突,就會造成編譯時錯誤:編譯器無法確定到底使用哪個來進行呼叫。

第二個錯誤是因為第一個無法確定呼叫哪一個而產生的後續錯誤。

又手賤點了個匿名……我是farmist

C建構函式過載的問題,C建構函式和解構函式可以過載嗎

你那不叫重灌,叫語法錯誤。你在定義hujiaoqi類的時候已經實現建構函式的過載了,即一專個是無參的建構函式hujiaoqi 一個是有參的hujiaoqi int 類的建構函式只呼叫一次,而且不管有多少個建構函式,屬只會呼叫其中一個,並且是在定義物件的時候自動呼叫的,具體是呼叫哪個根據定義物件時傳入...

C 的預設建構函式

a a2 這是一個函式宣告啊 名稱為 a2,返回值型別為 a 的函式 只是宣告,沒有執行,所以不會輸出 樓主要看清a1和a2具體是做什麼的 建構函式只有在產生物件或者是初始化的時候才會被呼叫預設的也是如此 這裡的a2 其生命形式為 a a2 顯然為一過程函式 返回型別 但這個函式 僅僅是一個宣告而已...

c 拷貝建構函式的細節問題

拷貝建構函式也是要你自己實現的阿,所以你要自己進行變數賦值了。如果你自己不實現,就給你一個預設的實現,就是所有資料拷過去。拷貝建構函式和賦值操作符不一樣,前者是新建物件,後者是賦值給已有物件。如果你不過載 操作符,編譯器也是給你一個預設的實現,就是把所有資料拷過去。第一個問題,拷貝建構函式函式體的構...