【发布时间】:2016-01-07 14:26:35
【问题描述】:
我是 C++ 新手(来自 C),正在编写一个类 B,它是另一个类 A 的成员。
如果父级尝试访问B 的容器中不存在的数据,成员B 将抛出异常(我抛出invalid_argument 异常)。成员 B 有一个对象,可以被认为是一个 STL 容器,因此在本例中就是如此。
我的问题是:如果我在A 中捕获了原始的 invalid_parameter 异常,是否认为重新抛出相同的异常是好的 C++ 实践(我会重新抛出原始错误,但我会在其中进行一些登录,所以what() 不同),或者我可以直接抛出std::exception。我的代码现在有很多
try { A.calls_b_exception } catch (std::invalid_argument& ie) {...} catch (std::exception& e) {...}
块,我想知道是否可以将它们减少到
try { A.calls_b_exception } catch (std::exception& e) {...}
并且仍然遵循良好的 C++ 范例。 与我的情况类似的示例代码:
class B
{
std::vector<int> stuff;
int get_value(int index)
{
if (index >= stuff.size()) {
stringstream err;
err << "--> invalid index " << index << " for stuff";
throw std::invalid_argument(err.str());
}
}
}
class A
{
B b;
// Assume there are methods to add a bunch of stuff to B
int get_value(int index)
{
try {
b.get_value();
} catch (std::invalid_argument& ie) {
stringstream err;
err << ie.what() << "\n\t--> A::get_value(" << index << ")";
// should I throw the same exception here or is this considered good C++ etiquette?
throw std::exception(err.str());
} catch (std::exception& e) {
throw; // something I was not anticipating handling happened
}
}
}
int main
{
A a;
// Assume more stuff to add to A
try {
a.get_value(-1);
}
catch (std::exception& e) {
stringstream err;
err << "--> invalid index " << index << " for main";
throw std::exception(err.str());exception here?
}
}
【问题讨论】:
-
错字?你的“我这样做”和“我应该这样做”是相同的。
-
在顶级异常处理程序中,您实际上并不知道异常来自哪里或它可能是什么,除非
try块中的代码是非常狭窄(就像你的单个函数调用)。除非我实际处理错误,否则我个人也不会捕获异常,只是用更详细的错误消息重新抛出它并不是“处理”错误,IMO。 -
My code now has many: try { A.calls_b_exception } catch (std::invalid_argument& ie) {...} catch (std::exception& e) {...}。如果您只记录它们,您实际上不必同时捕获它们。std::invalid_argument继承自std::exception。捕获std::exception也将捕获std::invalid_argument,您仍然可以访问what() 函数。try { A.calls_b_exception } catch (std::exception& e) {...}就好了。 -
@JoachimPileborg:我通过终止并最终打印错误来处理错误。为简洁起见,我只是在此示例中没有这样做,因为我更关心的主题是,只要用户在运行时知道原因,抛出更一般的异常是否是一种好的做法。我的 try 块很窄,所以我期望的唯一其他异常是不可预测的系统异常,这些异常也会导致程序提示退出。
-
@user1810087:我知道继承,但我不确定是否最好在 A 中捕获特定异常,并且在 A 中也有更一般的捕获以及其他可能的异常(我将在编辑中添加)。