如何“拒绝”实例化一个类
例如,如何“拒绝”实例化一个类
public class Test {
Test() {
if(xxx)//do some check here
//reject instancing class test.
}
}
我想我可以抛出一个异常拒绝它,是有没有其他办法? 我不知道是什么的实例化被否决的影响,但我认为一个自然的方法是:
Test test = new Test();//return null here indicating instancing rejected.
我希望Java和C++都应该有这种“拒绝”功能。
有内置的语言没有这样的功能,但你必须实现它的两个标准方法:
- 第一种是抛出异常。你在帖子中暗示了它。来电者需要预料到这个例外,并且准备好处理它。第二个是factory method。如果由于某种原因无法实例化您的类,它可能会返回null。您的呼叫者需要准备好处理来自工厂方法的空回报。
选择这两个选项并不容易。该指导原则是,如果拒绝实例化是例外情况,例如。编程或配置错误,然后转到异常路由。如果通常会发生拒绝,例如因为有些资源是暂时不可用,那么就去工厂方法路由。当然,这些规则也有例外,所以请使用您的最佳判断。
你不能从构造函数中返回null,但你可以(如你所建议的)抛出异常。
是的,如果您无法创建类的实例,则应该抛出异常。
如果你想返回null,你可以使用Factory pattern。例如。而不是Test test = new Test();
您可以编写Test test = TestFactory.CreateTest();
,并在TestFactory.CreateTest
中执行您所需的所有检查。
new Test()
总是返回一个非空实例Test
(至少在Java中)。
+1啊,很好的答案。 – 2012-02-16 04:58:41
我想我可以抛出一个异常拒绝
的确不错,从构造函数抛出异常将销毁所有子对象(如果使用继承)以及成员已经初始化。这是放弃构建对象的首选方法。
还有其他方法吗?
唯一的另一种方法是初始化为虚拟状态,并要求客户端代码检查构造函数是否使用特殊用途的方法成功运行。由于客户很容易忘记这种呼叫,我真的不推荐这种方法。
至于这个“解决方案”:
Test test = new Test();//return null here indicating instancing rejected.
有没有办法强迫new
从您的构造函数中返回一个空指针,所以这是行不通的。你可以模拟这种使用其他方法,如:
class Test
{
Test (...); // constructor that receives prepared arguments.
public:
static Test * create (...)
{
// prepare arguments...
if (successful) {
return new Test(prepared_arguments);
}
return 0;
}
};
,并使用该在你的代码:
Test * test = Test::create(...);
if (!test) {
// handle error.
}
但你仍然可以忘记检查空指针。
首选的方法是抛出异常。它更简单,始终有效,并且需要更少的打字。
在C++中,你不neccessarily有一个指针返回,考虑:
Test t; // run the constructor
因此,使用异常或工厂模式是唯一的方法来拒绝instanciation。
¤C++非常灵活,可以让您轻松定义这样的特征,作为[NOXNEW](简写为“no exception'new'”)的宏,如[我在此处显示](http://codepad.org/0jADRP8O)。我认为Java也是如此,但以某种不同的方式实现。但是,请注意通过这样做 - 返回nullpointer - 您将丢弃任何异常信息,这在某些情况下非常不合需要。然而,大概在这种情况下,你根本就不会这样做。但值得注意的是。 Cheers&hth。, – 2012-02-16 05:44:30
注意:在上面的答案中,我使用一个宏来传递可变数字参数,因为Visual C++ 10.0(当前版本)尚不支持可变参数模板,并且据我所知,它们将在Visual C++ 11中也不存在。对于完整的标准C++ 11来说,宏不是必需的。就此而言,借助一些图书馆支持,例如就像我在主博客上介绍的那样,C++ 03并不是必须的,尽管它使得更简单和更清晰的用法。干杯, – 2012-02-16 05:54:49
另外,现在你让我思考了,我认为代码可以大大简化。这是简化工作。当你完成它时,你想知道原来的代码如何可能如此愚蠢复杂,但我只是直接给你,只需很少的工作。 :-) – 2012-02-16 05:57:16