如何“拒绝”实现一堂课

时间:2012-02-16 04:48:33

标签: java c++

例如,

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 ++都应该有这种“拒绝”功能。

6 个答案:

答案 0 :(得分:7)

如果要返回null,可以使用Factory pattern。例如。而不是Test test = new Test();您可以编写Test test = TestFactory.CreateTest();,并在TestFactory.CreateTest中实施所需的所有检查。

new Test()总是返回Test的非空实例(至少在Java中)。

答案 1 :(得分:2)

你不能从构造函数返回null,但是你可以(按照你的建议)抛出异常。

答案 2 :(得分:1)

是的,如果您无法创建该类的实例,则应抛出异常。

答案 3 :(得分:1)

该语言没有内置这样的功能,但您有两种标准的实现方式:

  • 第一个是抛出异常。你在帖子中暗示了它。调用者需要预期此异常,并准备好处理它。
  • 第二个是factory method。如果由于某种原因无法实例化您的类,它可能会返回null。您的调用者需要准备好从您的工厂方法处理null返回。

在两个选项之间进行选择并不容易。指南是,如果拒绝实例化是例外情况,例如编程或配置错误,然后转到异常路由。如果拒绝经常发生,例如因为某些资源暂时不可用,所以请转到工厂方法路由。当然这些规则也有例外,所以请用你最好的判断。

答案 4 :(得分:0)

  

我想我可以抛出异常拒绝它

确实如此,从构造函数中抛出异常会破坏所有子对象(如果使用继承)并且已经初始化了成员。这是中止对象构造的首选方法。

  

还有其他方法吗?

唯一的另一种方法是初始化为虚拟状态,并要求客户端代码检查构造函数是否使用特殊用途方法成功运行。由于客户容易忘记这样的电话,我真的不推荐这种方法。

至于这个“解决方案”:

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.
}

但你仍然可以忘记检查空指针。

首选方法是抛出异常。它更简单,总是有效并且需要更少的打字。

答案 5 :(得分:0)

在C ++中,您不一定要返回指针,请考虑:

Test t; // run the constructor

因此,使用异常或工厂模式是拒绝实例化的唯一方法。