之後被釋放,我知道Object *pObject=new Object
包含兩個步驟:如果分配的內存構造函數拋出異常
- 運營商新的分配內存
- 調用對象的構造函數。
,並呼籲delete pObject
:
- 調用對象的銷燬;
- 運算符刪除以釋放內存。
但是,當新的Object進程,如果第2步拋出異常,如果運算符刪除被系統調用來釋放內存?
之後被釋放,我知道Object *pObject=new Object
包含兩個步驟:如果分配的內存構造函數拋出異常
,並呼籲delete pObject
:
但是,當新的Object進程,如果第2步拋出異常,如果運算符刪除被系統調用來釋放內存?
不,不會調用析構函數。由於對象構造不當,因此調用析構函數是不安全的。但是,如果任何成員對象已經完全構建,那麼它們將被破壞(當對象完成時)。
有人建議不要扔在構造函數中,我相信它比殭屍狀態更好,它類似於錯誤代碼並製作冗長的代碼。只要你遵循RAII,你應該沒問題(每個資源都由它自己的對象來管理)。在你拋出構造函數之前,確保你清理了所有你已經完成的任何事情,但是,如果你使用的是RAII,那應該什麼也不是。
下輸出 「B」:
#include <iostream>
struct B {
~B() { std::cout << "B" << std::endl; }
};
struct A {
A() : b() { throw(1); }
~A() { std::cout << "A" << std::endl; }
B b;
};
int main() {
try {
A *a = new A;
delete a;
} catch(int a) {}
}
編輯: 上面沒有你問,是delete操作符被調用,http://www.cplusplus.com/reference/new/operator%20delete []說:
「這些釋放函數由delete-expressions和new-expressions調用,以便在破壞(或未能構造)具有動態存儲持續時間的對象後釋放內存。
這可以通過覆蓋運營商delete
來測試。
是的,操作員刪除將被調用來釋放分配的內存。
下面的程序可以證明:
#include <iostream>
using std::cout;
using std::endl;
class A {
public:
A() { cout << "A() at " << this << endl; throw 1; }
~A() { cout << "~A() at " << this << endl; }
};
int main(int argc, char *argv[]) {
int N = 3;
for (int i = 0; i < N; ++i) {
try {
new A;
} catch (int a) {
// pass
}
}
return 0;
}
運行我的系統上這個節目,我發現結果打印出來是這樣的:
A() at 0x2170010
A() at 0x2170010
A() at 0x2170010
顯然,析構函數不要撥打因爲沒有
~A() at 0x2170010
行被打印出來。
而操作符刪除肯定會被調用,因爲三個對象的地址完全相同。
不要在構造函數中拋出異常。 –
@EdHeal,爲什麼不呢?這似乎是構建對象時處理錯誤的常用方法之一,並且在正確編寫對象時不應該泄漏或任何內容。 – chris
是的,調用'operator new'的相同格式的'operator delete'將被調用。 – songyuanyao