我正在查看Google C ++样式指南,他们已经决定not to use exceptions in C++ code,而是依赖于返回值。
我的问题是:在这种情况下,你如何处理构造函数中的失败,因为你不能在那些函数中返回值。
谢谢!
答案 0 :(得分:7)
我的第一直觉是将失败点从构造函数中取出,并创建一个初始化方法。
这样你可以创建你的对象而不用担心失败,然后调用init()函数。该函数可以返回类似int的成功/失败,例如,如果发生故障,则返回-1。
是的,这是一个额外的步骤,但它确实让你无法使构造函数失败
答案 1 :(得分:4)
这很丑陋,但这样做的方法是保留对象的“特殊状态”,意思是“构造失败”。然后你必须查询该状态。啊!
答案 2 :(得分:2)
他们在构造函数中基本上什么都不做。
同样来自Google C ++风格指南: 在构造函数中工作 链接▶ 通常,构造函数应该只将成员变量设置为其初始值。任何复杂的初始化都应该采用显式的Init()方法。
答案 3 :(得分:2)
您可以执行以下操作:
class X;
class Y;
class Foo
{
public:
//! This function validates the input, and returns an error status if
//! the Foo can not be created. Otherwise we return a successful status
//! and output points to a newly constructed Foo. The Foo constructor
//! is only called once the inputs are validated.
//! No exceptions are thrown.
static Status buildInstance(X const& x, Y const& y, std::auto_ptr<Foo>& output);
private:
Foo(X const& x, Y const& y);
};
我过去经常使用这种模式(因为我不得不),但是说,我更喜欢我的构造函数抛出异常。上述情况充其量是不优雅的,最糟糕的是相当繁琐。
答案 4 :(得分:2)
我是C ++的新手,所以我的意见不值得这么多;但我至少遇到过几种不同的方法。
在我最近使用的一个库中,每个构造函数都有一个int&
参数,它返回构造的状态;此库的文档声明如果构造结果无效,它将调用未定义的行为。这种方法使调用者有责任确保不使用无效类。
TheClass::TheClass(int &result)
{
result = -1; // or some error value
// do lots of initialisation
result = 0; // success
}
我看到的另一个有is_valid()
方法。如果构造失败,则将布尔成员变量设置为false并从此is_valid()
方法返回(此方法还检查了其他一些内容)。我设法看到了这个源,并发现每个成员函数都以if(is_valid())
语句开头。我不能说我是这种方法的粉丝。
TheClass::TheClass() : m_valid(false)
{
// do the initialisation
if (everything_ok)
m_valid = true;
}
void TheClass::method()
{
if (!is_valid()) return;
// do some work
}
我最近读到过,异常并不像过去那样缓慢和笨拙,而且可以优雅地实现它们。谷歌可能出于任何原因禁止它们,但它们仍然是C ++语言的一部分。你可以使用你提供的工具,而不是用螺丝刀建造房屋。
答案 5 :(得分:1)
您可以设置一个类/对象字段来检查是否发生错误。