C ++抛出类成员 [英] C++ throwing class members
问题描述
我有以下C ++代码
template <class E>
class ExceptionWrapper {
public:
explicit ExceptionWrapper(const E& e): e(e) {}
void throwException() {
throw e;
}
private:
E e;
};
...
try {
ExceptionWrapper<E> w(...);
w.throwException();
} catch (const E& e) {
...
}
...
问题:此代码有效吗?我可以说,返回对类成员的引用几乎总是无效的(我相信大家都同意这个声明)。但是,我的同事声称, throw
不是这种情况。
Question: is this code valid? I could argue that returning a reference to the class member is almost always not valid (and I am sure everybody agrees with this statement). However, my colleague claims that this is not the case with throw
.
在改变 catch(const E& e)
到 catch(E e)
后,一个讨厌的bug似乎消失了, - 此代码不是有效。
P.S. after changing catch (const E& e)
to catch (E e)
a nasty bug seemingly disappeared which strengthens my position - that this code is not valid.
推荐答案
通过引用捕获e是无效的,因为e是w的成员,w在捕获范围内不存在。
my claim is that catching e by reference is not valid since e is a member of w and w is not alive in the catch scope.
是不正确的。 throw e;
抛出成员的副本,该副本在catch的范围内有效。
Your claim is incorrect. throw e;
throws a copy of the member, and that copy is valid in catch's scope.
3(n3797草稿):
§ 15.1 / 3 (n3797 draft):
抛出异常副本 - 初始化(
8.5
,
12.8
)一个临时对象,称为
异常对象
。
临时值是一个左值,用于初始化在匹配的
处理程序
(
15.3
)中命名的变量。如果
类型的异常对象是一个不完整的类型或指向一个不完整类型的指针,而不是
(可能是cv-qualified)
void
程序是不成形的。评估
throw-expression
使用操作数throws
异常;异常对象的类型是通过从操作数的
静态类型中删除任何顶级的
cv-qualifiers
并从
T $的数组中调整类型来确定的b $ b或函数返回
T
为指向
T
或指向函数返回
T
。
Throwing an exception copy-initializes ( 8.5 , 12.8 ) a temporary object, called the exception object . The temporary is an lvalue and is used to initialize the variable named in the matching handler ( 15.3 ). If the type of the exception object would be an incomplete type or a pointer to an incomplete type other than (possibly cv-qualified) void the program is ill-formed. Evaluating a throw-expression with an operand throws an exception; the type of the exception object is determined by removing any top-level cv-qualifiers from the static type of the operand and adjusting the type from "array of T " or "function returning T " to "pointer to T " or "pointer to function returning T ," respectively.
通过const引用捕获是捕获异常的首选方法。它允许捕获 std :: exception
的导数,而不会对异常对象进行切片。
Catching by const reference is the preferred way to catch exceptions. It allows catching derivatives of std::exception
without slicing the exception object.
这篇关于C ++抛出类成员的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!