是否可以对构造函数抛出异常的对象进行异常处理,该对象的异常处理接近其基于堆栈的代码创建
Can exception handling of object whose constructor throw an exception be near its stack-based creation on code?
我正在尝试使我的C++代码异常安全,并遇到了一个问题,询问朋友或搜索网络都无济于事。
根据我的理解,当使用构造函数创建对象时可能会引发异常,创建代码需要用try
块括起来,异常处理是在catch(){}
中完成的。
如果创建是基于堆的(例如 new
使用默认分配器),我可以像这样将异常处理代码放在创建附近:
void f() {
// work unrelated to Hoge object here
try {
Hoge *pHoge = new Hoge(); // could throw an exception
} catch(HogeException& ex) {
// handle exception
}
// rest of work here
}
但是,如果创建是基于堆栈的,由于块的范围,我找不到这样做的方法并求助于下面的代码try
:
void g() {
// work unrelated to Hoge object here
try {
Hoge hoge; // could throw an exception
// rest of work here
} catch(HogeException& ex) {
// handle exception
}
}
如果上面的// rest of work
代码很大,对象创建和异常处理之间的位置距离可能会很长,从而降低代码的可读性......
我更喜欢异常处理代码靠近对象创建(也许这是try
- catch
结构的概念之一)。有什么解决办法吗?
将
// rest of work
委托给帮助程序函数,并将Hoge&
传递给该函数:
void RestOfWork(Hoge& hoge)
{
// rest of work here
}
void g() {
// work unrelated to Hoge object here
try {
Hoge hoge;
RestOfWork(hoge);
// rest of work here
} catch(HogeException& ex) {
// handle exception
}
}
顺便说一句,Hoge hoge();
并没有做你认为它做的事情。 您可能认为您正在声明一个名为 hoge
的类型为 Hoge
的对象,并通过调用默认构造函数对其进行初始化。 您实际上正在做的是声明一个名为 hoge
的函数,该函数不带任何参数并返回Hoge
by-value。 我已经在上面的代码中修复了这个问题。
编辑 事实上,正如@LightnessRacesInOrbit所建议的,Hoge
对象的构造也可以在延迟函数中进行,例如:
void RestOfWork()
{
Hoge hoge;
// rest of work here
}
void g() {
// work unrelated to Hoge object here
try {
RestOfWork();
} catch(HogeException& ex) {
// handle exception
}
}
执行此操作的合理方法是使用可为空的单项容器,例如 boost::optional
:
void g() {
// work unrelated to Hoge object here
boost::optional<Hoge> opt_hoge;
try {
opt_hoge = boost::in_place<Hoge>();
} catch(HogeException& ex) {
// handle exception
}
Hoge &hoge = *opt_hoge;
// rest of work here
}
如果您不能使用 Boost,std::unique_ptr
将以堆分配为代价:
void g() {
// work unrelated to Hoge object here
std::unique_ptr<Hoge> opt_hoge;
try {
opt_hoge = std::unique_ptr<Hoge>(new Hoge);
} catch(HogeException& ex) {
// handle exception
}
Hoge &hoge = *opt_hoge;
// rest of work here
}
相关文章:
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 创建具有 new in 函数和"this is nullptr"异常的对象
- 当我使用 C++ 中的 C# dll 来使用 Selenium 时,存在异常处理问题
- 堆异常 -1073741510对象
- Firebase C++VS2018 SDL2-在Firebase::app::create(..)上执行异常处理
- 使用 stoi 功能进行异常处理
- 子系统中的异常处理:本机
- 与异常处理程序中的操作员<<不匹配
- 数组 C++ 上的异常处理程序
- 异常处理:如果用户输入不是三个特定字符之一
- C++ 异常处理错误输出
- 视觉 std::矢量无异常:警告 C4530:使用了C++异常处理程序,但未启用展开语义.指定 /EHsc
- C++交换机状态异常处理
- 在字符串类上的成员函数和out_of_range异常处理
- C++ 异常处理:将异常定义为对象
- 是否可以对构造函数抛出异常的对象进行异常处理,该对象的异常处理接近其基于堆栈的代码创建
- 插入>>运算符重载:从 CIN 检索对象的 CTOR 参数时的异常处理
- C++堆栈对象的构造函数异常处理
- 视觉对象 关于C++异常处理
- 异常处理需要面向对象编程吗?