从析构函数中抛出 [英] Throw from a destructor

查看:62
本文介绍了从析构函数中抛出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C ++ ers:


我有这位朋友认为C ++不能从析构函数中抛出。


我认为从析构函数是坏的Karma,应该设计为
左右,但是C ++不能严格阻止实际事件。


(一个编译器导向的原因是编译器可能无法检测到来自析构函数的调用树导致抛出的
。)


换句话说,假设我有一个大对象,aBigSimCity,它有一个

..shutdown()方法。它必须在~BigSimCity()调用之前调用,它可能会抛出
。这意味着我的Wrapper类,包含aBigSimCity,永远不应该像这样声明一个析构函数:~Wrapper(){aBigSimCity.shutdown(); }。


..shutdown()可能会抛出,我不想把它包装在

try {} catch()中。 ~Wrapper不应该抛出,因此我需要一个更好的系统来

分解。


我们哪个人是对的?


-

Phlip

C++ers:

I have this friend who thinks C++ cannot throw from a destructor.

I think throwing from a destructor is bad Karma, and should be designed
around, but that C++ cannot strictly prevent the actual event.

(One compiler-oriented reason is a compiler might not be able to detect
that the call-tree from a destructor leads to a throw.)

Put another way, suppose I have a big object, aBigSimCity, and it has a
..shutdown() method. It must call before ~BigSimCity() calls, and it might
throw. This implies my Wrapper class, containing aBigSimCity, should never
declare a destructor like this: ~Wrapper() { aBigSimCity.shutdown(); }.

..shutdown() might throw, and I don''t feel like wrapping it in
try{}catch(). ~Wrapper should not throw, hence I need a better system to
break things down.

So which of us is right?

--
Phlip

推荐答案

Phlip写道:
Phlip wrote:

我有这个朋友认为C ++不能从析构函数中抛出。


我认为从析构函数中抛出是糟糕的Karma,应该设计好

左右,但是C ++不能严格阻止实际事件。


(一个编译器导向的原因是编译器可能无法检测到

来自析构函数的调用树导致抛出。)


换句话说,假设我有一个大对象,aBigSimCity,它有一个

.shutdown()方法。它必须在~BigSimCity()调用之前调用,它可能会抛出
。这意味着我的Wrapper类,包含aBigSimCity,永远不应该像这样声明一个析构函数:~Wrapper(){aBigSimCity.shutdown(); }。


.shutdown()可能会抛出,我不想把它包装在

try {} catch()中。 ~Wrapper不应该抛出,因此我需要一个更好的系统来确定

I have this friend who thinks C++ cannot throw from a destructor.

I think throwing from a destructor is bad Karma, and should be designed
around, but that C++ cannot strictly prevent the actual event.

(One compiler-oriented reason is a compiler might not be able to detect
that the call-tree from a destructor leads to a throw.)

Put another way, suppose I have a big object, aBigSimCity, and it has a
.shutdown() method. It must call before ~BigSimCity() calls, and it might
throw. This implies my Wrapper class, containing aBigSimCity, should never
declare a destructor like this: ~Wrapper() { aBigSimCity.shutdown(); }.

.shutdown() might throw, and I don''t feel like wrapping it in
try{}catch(). ~Wrapper should not throw, hence I need a better system to
break things down.



忘了提到为什么这不是常见问题:

http://www.parashift.com/c++-faq-lit....html#faq-17.3


假设Wrapper对象包含一个catch(...)来处理任何

异常。所以在这个特定的情况下,Wrapper的析构函数可以在抛出异常时从未调用时调用
,所以它的

析构函数总能安全地调用可能会抛出。


无论如何都不要这样做。


-

Phlip

Forgot to mention why this isn''t a FAQ:

http://www.parashift.com/c++-faq-lit....html#faq-17.3

Suppose the Wrapper object contains a catch(...) that takes care of any
exceptions. So in this specific case, the Wrapper''s destructor can
never be called during un-winding from a thrown exception, so its
destructor can always safely call things that might throw.

Don''t do it anyway.

--
Phlip


Phlip写道:
Phlip wrote:

C ++ ers:


我有这个认为C ++不能从析构函数中抛出的朋友。


我认为从析构函数中抛出的是糟糕的Karma,并且应该被设计为

左右,但是C ++不能严格防止实际事件。


(一个编译器导向的原因是编译器可能无法检测到
来自析构函数的调用树导致扔掉。)


换句话说,假设我有一个大对象,aBigSimCity,它有一个

..shutdown()方法。它必须在~BigSimCity()调用之前调用,它可能会抛出
。这意味着我的Wrapper类,包含aBigSimCity,永远不应该像这样声明一个析构函数:~Wrapper(){aBigSimCity.shutdown(); }。


..shutdown()可能会抛出,我不想把它包装在

try {} catch()中。 ~Wrapper不应该抛出,因此我需要一个更好的系统

分解。


我们哪个人是对的?
C++ers:

I have this friend who thinks C++ cannot throw from a destructor.

I think throwing from a destructor is bad Karma, and should be designed
around, but that C++ cannot strictly prevent the actual event.

(One compiler-oriented reason is a compiler might not be able to detect
that the call-tree from a destructor leads to a throw.)

Put another way, suppose I have a big object, aBigSimCity, and it has a
..shutdown() method. It must call before ~BigSimCity() calls, and it might
throw. This implies my Wrapper class, containing aBigSimCity, should never
declare a destructor like this: ~Wrapper() { aBigSimCity.shutdown(); }.

..shutdown() might throw, and I don''t feel like wrapping it in
try{}catch(). ~Wrapper should not throw, hence I need a better system to
break things down.

So which of us is right?



你!


我倾向于在我的析构函数(特别是虚拟)中添加一个throw()来表示

表示他们不会扔。


-

Ian Collins。

You!

I tend to add a throw() to my destructors (especially virtual) to
indicate that they will not throw.

--
Ian Collins.


Phlip写道:
Phlip wrote:

C ++ ers:


我有这位朋友认为C ++不能从析构函数中抛出。


我认为从析构函数中抛出的是糟糕的Karma,并且应该设计为

左右,但C ++不能严格阻止实际事件。


(一个面向编译器的原因是编译器可能无法检测到
来自析构函数的调用树导致抛出。)

$ b $换句话说,假设我有一个大对象,aBigSimCity,它有一个

.shutdown()方法。它必须在~BigSimCity()调用之前调用,它可能会抛出
。这意味着我的Wrapper类,包含aBigSimCity,永远不应该像这样声明一个析构函数:~Wrapper(){aBigSimCity.shutdown(); }。


.shutdown()可能会抛出,我不想把它包装在

try {} catch()中。 ~Wrapper不应该抛出,因此我需要一个更好的系统来

分解。


我们哪个人是对的?
C++ers:

I have this friend who thinks C++ cannot throw from a destructor.

I think throwing from a destructor is bad Karma, and should be designed
around, but that C++ cannot strictly prevent the actual event.

(One compiler-oriented reason is a compiler might not be able to detect
that the call-tree from a destructor leads to a throw.)

Put another way, suppose I have a big object, aBigSimCity, and it has a
.shutdown() method. It must call before ~BigSimCity() calls, and it might
throw. This implies my Wrapper class, containing aBigSimCity, should never
declare a destructor like this: ~Wrapper() { aBigSimCity.shutdown(); }.

.shutdown() might throw, and I don''t feel like wrapping it in
try{}catch(). ~Wrapper should not throw, hence I need a better system to
break things down.

So which of us is right?



(Scott Meyer的Effective C ++第3版,第8项完全解决了这个问题。)

怎么样(几乎是逐字逐句)这本书):


class BigSimCity

{

void shutdown()

{

//做可能扔的东西

closed_ = true;

}

~BigSimCity()//这会有一个空的throw()规范吗?

{

if(!closed)

{

try {shutdown (); }

catch(...){// log or something}

}

}

private:

bool关闭;

};


如果客户需要,您可以让客户自行关闭() br />
自己抓住它。如果没有,那么由

析构函数调用shutdown()。


Joe

(Scott Meyer''s Effective C++ 3rd edition, Item 8 addresses exactly this.)
How about something like (almost verbatim from the book):

class BigSimCity
{
void shutdown()
{
// do stuff that may throw
closed_ = true;
}
~BigSimCity() // would this have an empty throw() specification?
{
if (!closed)
{
try { shutdown(); }
catch (...) { // log or something }
}
}
private:
bool closed;
};

You give the client the chance to shutdown() on their own if they want
catch it on their own. And if not, then shutdown()''s called by the
destructor.

Joe


这篇关于从析构函数中抛出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆