CPPEXP —— 構(gòu)造函數(shù)拋異常
說(shuō)明
類的構(gòu)造函數(shù)拋出異常,不會(huì)調(diào)用該類的析構(gòu)函數(shù),資源的釋放原則是編譯器申請(qǐng)的編譯器負(fù)責(zé),程序員申請(qǐng)的程序員負(fù)責(zé)。
在實(shí)驗(yàn)代碼中,子類Except的構(gòu)造函數(shù)拋出異常,則Base和mMember1的構(gòu)造函數(shù)是編譯器調(diào)用,因此編譯器會(huì)調(diào)用它們的析構(gòu)函數(shù),而mMember2由程序員主動(dòng)使用new生成,因此需要程序員主動(dòng)使用delete。
解決方法:
- 在構(gòu)造函數(shù)中使用
try...catch結(jié)構(gòu) - 使用類包裝資源申請(qǐng),如auto_ptr。
實(shí)驗(yàn)代碼
/*** @file constructor_exception.cpp* @brief 測(cè)試構(gòu)造函數(shù)異常引起的行為* @copyright public domain*/#include <iostream>#include <exception>#include <memory>class Base {public:Base() { std::cout << "Base()" << std::endl; }virtual ~Base() { std::cout << "~Base()" << std::endl; }};class Member {public:Member(int id):mId(id) { std::cout << "Member():" << mId << std::endl; }virtual ~Member() { std::cout << "~Member()" << mId << std::endl; }protected:int mId;};class Except : public Base {public:Except() : mMember1(1), mMember2(NULL) {std::cout << "Except() enter" << std::endl;mMember2 = new Member(2);mMember3.reset(new Member(3));throw std::exception();std::cout << "Except() leave" << std::endl;}virtual ~Except() {delete mMember2;std::cout << "~Except()" << std::endl;}protected:Member mMember1;Member *mMember2;std::auto_ptr<Member> mMember3;};int main() {try {Except e;} catch (std::exception& e) {std::cout << e.what() << std::endl;}return 0;}
運(yùn)行及結(jié)果
$ g++ constructor_exception.cpp
$ ./a.out
Base()
Member():1
Except() enter
Member():2
Member():3
~Member()3
~Member()1
~Base()
std::exception
posted on 2016-04-30 10:17 lemene 閱讀(434) 評(píng)論(0) 編輯 收藏 引用

