我在尝试找到一种解决方案时遇到了困难,该解决方案允许我将对象的范围保留在主方法的本地,同时捕获潜在的初始化异常。
下面的伪代码试图最好地说明我的问题。
int main () {
// Initialisation
SomeObject * object;
try {
SomeObject obj; // Initialisation can cause an exception
object = &obj;
}
catch (SomeException &ex) {
// Handle exception
}
// object out of scope undefined behaviour
// Application Logic
return 0;
}
我知道一旦 try 块结束,该对象将被删除,因此使用指针将导致未定义的行为。
如何执行此操作并将对象传递给函数范围,以便不删除对象?
我可以在我的项目中使用 c++14 解决方案。
如何执行此操作并将对象传递给函数范围,以便不删除对象?
您可以改用智能指针:
int main () {
// Initialisation
std::unique_ptr<SomeObject> object;
try {
object = std::make_unique<SomeObject>(); // Initialisation can cause an exception
}
catch (SomeException &ex) {
// Handle exception
}
if(object) {
// Application Logic
}
return 0;
}
显而易见的方法是"函数尝试块">
int main() try
{
SomeObject object;
// Application logic - able to use object
return 0;
}
catch (SomeException &ex)
{
// Handle exception
}
这允许异常处理程序在程序终止之前进行清理。
如果您希望异常处理程序在 main()
中,那么一个选项是
int main()
{
try
{
SomeObject object;
// Application logic able to use object
}
catch (SomeException &ex)
{
// Handle exception
}
}
通过适当的控制结构(例如,循环内的整个try
/catch
(,catch
块可以从错误中恢复并重新开始。
如果你真的希望对象的定义和初始化是分开的,你可以做一些事情(C++11 及更高版本(;
#include <memory>
int main ()
{
std::unique_ptr<SomeObject> object;
try
{
object = std::make_unique<SomeObject>();
}
catch (SomeException &ex)
{
// Handle exception
}
// code here cannot assume construction of object succeeded
if (object)
{
// Application Logic can assume object is properly constructed
}
return 0;
}
在 C++11 之前,上述可以使用 std::auto_ptr
(在 C++11 中已弃用,有利于 unique_ptr
。
合适的选择取决于您是希望"应用程序逻辑"能够假设object
已正确构造(即在对象构造成功之前永远不会执行应用程序逻辑(,还是必须测试失败的可能性。