我有一个从外部文件加载的类,因此理想情况下,如果加载失败,我希望它的构造函数从给定路径加载,如果找不到/不可读文件,我将要抛出错误(抛出错误构造函数不是一个可怕的主意,请参阅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
}
这行得通,但是在很大程度上违背了使用构造函数的目的,因此我也不是很喜欢。
所以我的问题是,构造对象的这些方法中,哪一种可能最好(或最少坏),这可能会在构造函数中引发错误?有更好的方法吗?
因为可能需要在程序第一次启动时创建对象,然后在以后停止它。在最极端的情况下(在这种情况下我实际上也确实需要)实际上是:
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] 删除。
我来说两句