C ++,处理构造函数的异常

尼古拉

我有一个从外部文件加载的类,因此理想情况下,如果加载失败,我希望它的构造函数从给定路径加载,如果找不到/不可读文件,我将要抛出错误(抛出错误构造函数不是一个可怕的主意,请参阅ISO的FAQ)。

但是,这有一个问题,我想以某种受控方式自己处理错误,并且我想立即执行此操作,因此我需要在该对象的构造函数周围放置一个try-catch语句...如果执行也就是说,该对象未在try语句之外声明,即:

//in my_class.hpp
class my_class
{
    ...
public:
    my_class(string path);//Throws file not found, or other error error
    ...
};


//anywhere my_class is needed
try
{
   my_class my_object(string);
}
catch(/*Whatever error I am interesetd in*/)
{
   //error handling
}
//Problem... now my_object doesn't exist anymore

我尝试了多种方法来解决它,但是我真的不喜欢其中任何一种方法:

首先,我可以使用指向my_class的指针来代替类本身:

my_class* my_pointer;
try
{
   my_class my_pointer = new my_class(string);
}
catch(/*Whatever error I am interesetd in*/)
{
   //error handling
}

问题在于该对象的实例并不总是以创建该对象的对象结尾,因此正确删除所有指针很容易出错,此外,我个人认为将某些对象作为指针是很丑陋的物体,而大多数物体是“常规物体”。

其次,我可以以几乎相同的方式使用仅包含一个元素的向量:

std::vector<my_class> single_vector;
try
{
   single_vector.push_back(my_class(string));
   single_vector.shrink_to_fit();
}
catch(/*Whatever error I am interesetd in*/)
{
   //error handling
}

我不喜欢有很多单元素矢量的想法。

第三,我可以创建一个空的人造构造函数并使用另一个加载函数,即

//in my_class.hpp
class my_class
{
    ...
public:
    my_class() {}// Faux constructor which does nothing
    void load(string path);//All the code in the constructor has been moved here
    ...
};


//anywhere my_class is needed
my_class my_object
try
{
   my_object.load(path);
}
catch(/*Whatever error I am interesetd in*/)
{
   //error handling
}

这行得通,但是在很大程度上违背了使用构造函数的目的,因此我也不是很喜欢。

所以我的问题是,构造对象的这些方法中,哪一种可能最好(或最少坏),这可能会在构造函数中引发错误?有更好的方法吗?

编辑:为什么不只在try语句中使用对象

因为可能需要在程序第一次启动时创建对象,然后在以后停止它。在最极端的情况下(在这种情况下我实际上也确实需要)实际上是:

int main()
{
   try
   {
    //... things which might fail

    //A few hundred lines of code
   }
   catch(/*whaveter*/)
   {
   }
}

我认为这会使我的代码难以阅读,因为catch语句与实际出错的地方相去甚远。

弗朗索瓦·安德里厄

一种可能性是将构造和错误处理包装在一个函数中,返回构造的对象。范例:

#include <string>

class my_class {
public:
    my_class(std::string path);
};

my_class make_my_object(std::string path)
{
    try {
        return {std::move(path)};
    }
    catch(...) {
        // Handle however you want
    }
}

int main()
{
    auto my_object = make_my_object("this path doesn't exist");
}

但是请注意,该示例是不完整的,因为不清楚在构造失败时您打算做什么。catch块必须返回一些东西,抛出或终止。

  • 如果可以返回另一个实例,即状态为“坏”或“默认”的实例,my_class(std::string path)则可以在确定路径无效时将实例初始化为该状态因此,在这种情况下,不需要try/catch块。
  • 如果您抛出异常,那么首先捕获它是没有意义的。在这种情况下,也不需要try/catch块,除非您想做一些额外的工作,例如记录日志。
  • 如果要终止,则可以让异常未被捕获。同样,在这种情况下,不需要try/catch块。

真正的解决方案可能是根本不使用try/catch块,除非实际上有错误处理,否则您不应该执行此操作,因为my_class该问题在问题中不明显(也许是后备路径?)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

堆栈对象的C ++构造函数异常处理

来自分类Dev

C ++重载异常的构造函数

来自分类Dev

在C#自定义异常处理的情况下如何进行构造函数调用?

来自分类Dev

试图将构造函数设置为0的未处理异常-C ++

来自分类Dev

C#的自定义异常处理中的base()构造函数。它是如何工作的?

来自分类Dev

C ++类构造函数引发异常

来自分类Dev

在构造函数C ++中引发异常

来自分类Dev

使用move构造函数引发异常?(C ++)

来自分类Dev

C ++在构造函数中捕获异常

来自分类Dev

调用构造函数时异常的C ++行为

来自分类Dev

使用cython从C ++构造函数传播异常

来自分类Dev

在构造函数C ++中引发异常

来自分类Dev

构造函数中的异常 - C++

来自分类Dev

构造函数中的异常处理

来自分类Dev

创建异常时构造函数语法上的差异(C ++)

来自分类Dev

如何从C ++中的构造函数中捕获异常

来自分类Dev

在构造函数C ++中处理Try-catch块

来自分类Dev

C#-构造函数-更改处理程序对象

来自分类Dev

类构造函数中异常处理的行为

来自分类Dev

类构造函数中异常处理的行为

来自分类Dev

字体渲染函数C ++ SDL中未处理的异常

来自分类Dev

C ++ c-tor处理默认成员值构造异常?

来自分类Dev

C ++ c-tor处理默认成员值构造异常?

来自分类Dev

C ++,静态对象构造函数中的异常会绕过先前静态对象的析构函数

来自分类Dev

构造函数<X,Y>(C <Y>)和接口C <Y>的Java泛型异常行为

来自分类Dev

异常处理C#

来自分类Dev

如何从构造函数中捕获异常而不处理整个函数?

来自分类Dev

默认构造函数无法处理异常类型隐式超级构造函数引发的异常

来自分类Dev

我应该在哪里捕获构造函数中引发的C ++异常?

Related 相关文章

热门标签

归档