2011-10-25 45 views

回答

11

是的,你可以:抛出异常。这几乎是唯一明智的方法。通过选择合适的异常类(无论是标准还是自己的)并提供良好的错误信息等,您都可以告诉调用者出了什么问题。

FAQ has more details

+0

@userbb:请注意,任何完全构造的成员将被破坏,但对象本身的析构函数将不会被调用。 –

5

您需要抛出异常。这是处理失败对象创建的最佳方法。

Constructor Failures应该是Herb Sutter的GOTW中有趣的读物。

这样做的另一种方法是,如果构造函数遇到错误,请设置状态位并让用户调用IsOK()来查看构造是否真正起作用。

但是这被认为是陈旧的

赫伯说:

我已经找到了,“如果一个构造函数遇到错误,设置一个状态位,让用户调用ISOK(),看看是否建设的实际工作”已经过时,危险方法,单调乏味,绝不比抛出异常更好。

1

抛出一个异常是处理该异常的常用方法,但是,我劝阻你从构造函数中抛出异常的模式。

我们不能确保构造函数不会抛出异常,但在我看来依赖构造函数抛出的异常的反模式。 有一个微妙的区别:)

我通常更喜欢处理不应该失败的构造函数,并移动在可以返回值或抛出异常的Initialize方法中失败的合理逻辑。

它更干净,避免你在代码变得更加复杂的时候头疼!

这就是为什么我这么blieve一个例子:http://www.cs.technion.ac.il/~imaman/programs/throwingctor.html

另一个有趣的帖子是C++ : handle resources if constructors may throw exceptions (Reference to FAQ 17.4]

+0

我没有downvote,但是,你不能总是写一个不能失败的构造函数。我想你是在暗示两个对Symbian使用的两阶段构造。 –

+0

是的,你不可能总是写一个不能失败的构造函数,但是从我的角度来看,避免依赖构造函数抛出的异常是一种好的做法。一个例子当然是内存不足。 –

+0

我必须承认,像两个分阶段构建方法,不是所有的类,但在处理文件或大量的内存或互联网连接的类似乎是我的最佳选择。我不知道Symbian使用这种方法,但我发现它被用于很多语言和库(C++,C#和Java)。 –

1

如AIX解释,从构造函数抛出是唯一明智的选择。

或者,你可以使用命名的构造函数用法(见herehere)和是否有新对象的创建失败结束返回空指针。

+1

同意在那些你必须有两阶段构造的情况下,最好减少构造函数的可访问性并使用“命名构造函数”来创建对象。缺点 - 大多数实现依赖于堆分配(尽管这不是什么坏处)。 –