c++析构函数中抛出异常问题

#include <iostream>
/*
	不要在析构函数中抛出异常 
 */
class A {
	public:
		A() {}
		~A() { std::cout << "A析构了.." << std::endl; }
};

/*
	析构函数调用规则:
	先调用成员析构
	再调用派生类析构
 */
//析构函数绝对不要抛出异常
class B : public A{
	public:
		B() {}
		~B() { std::cout << "B析构了.. " << std::endl; 
		throw std::string("B error"); } // 编译器默认析构函数: inline ~B() noexcept {}
	//编译器默认析构函数实现:
	/*
		inline ~B() noexcept {
			try {
			
			} catch(...) {
				std::terminate();	
				//析构函数绝对不要抛出异常
			}
		} 
	 */
	private:
		std::string m_value;
		/*
			在掉~B() 析构时候, 先调用 m_value的析构,再调用派生类 ~A();
		 */
};
void testClass_1() { //测试析构
	B *b = new B;
	delete b;
}
class EvilB : public B {
	public:
		~EvilB() noexcept(false) { throw std::string("error"); }
};
void testEvilB() {
	try {
		EvilB *b = new EvilB();	
		delete b;
		
	} catch(std::string e) {
		//没有捕获到异常,编译器已经调用std::terminate(),且程序崩溃
		//因为编译器为析构函数默认加入关键字 noexcept,可以加入关键字 noexcept(false) 
		//问题1 : 派生类虽然能够析构,若派生类析构函数也抛出异常,则程序就挂.
		//出现抛出两个异常, 则无法捕获.
		//问题2 : 若声明两次EvilB对象,析构两次时,则程序就会崩溃.
		std::cout << "catch your evil: " << e <<  std::endl;
	}
}
int main(void) {
	testEvilB();
	return 0;
}
posted @ 2020-02-24 18:52  i0gan  阅读(650)  评论(0编辑  收藏  举报