如何"reject"实例化类
How "reject" instancing a class
例如,
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++都应该有这个"拒绝"特性。
如果您想返回null,可以使用Factory模式。例如,您可以编写Test test = TestFactory.CreateTest();
,而不是Test test = new Test();
,并在TestFactory.CreateTest
中实现所需的所有检查。
new Test()
总是返回Test
的非null实例(至少在Java中是这样)。
您不能从构造函数返回null,但您可以(按照您的建议)抛出异常。
语言中没有这样的功能,但有两种标准的实现方法:
- 第一个是抛出异常。你在帖子中暗示了这一点。调用方需要预期此异常,并做好处理准备
- 第二种是工厂方法。如果由于任何原因未能实例化您的类,它可能会返回null。调用方需要准备好处理来自工厂方法的null返回
在这两个选项之间做出选择并不容易。指导原则是,如果拒绝实例化是异常情况,例如编程或配置错误,则执行异常路线。如果拒绝将定期发生,例如因为某些资源暂时不可用,则采用工厂方法。当然,这些规则也有例外,所以请用你最好的判断。
是的,如果无法创建类的实例,则应该抛出异常。
我想我可以抛出一个异常来拒绝它
的确,从构造函数抛出异常将销毁所有子对象(如果使用继承)和已经初始化的成员。这是中止对象构造的首选方式。
还有别的办法吗?
唯一的其他方法是初始化为伪状态,并要求客户端代码检查构造函数是否使用专用方法成功运行。由于客户很容易忘记这样的电话,我真的不推荐这种方法。
关于这个"解决方案":
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++中,您不需要返回指针,请考虑:
Test t; // run the constructor
因此,使用异常或工厂模式是拒绝通知的唯一方法。
- 从C++实例化QML
- 设计一个只能由特定类实例化的类(如果可能的话,通过make_unique)
- 如何创建一个空的全局类并在启动时实例化它
- 在两个类中共享相同的函数调用,并在不需要时避免空实例化
- 约束和显式模板实例化
- 为什么包含windows.h会产生语法错误,从而阻止类的实例化?(C2146,C2065)
- 对象实例化调用构造函数的次数太多
- 如何使用非默认构造函数实例化模板化类
- 静态数据成员模板专用化的实例化点在哪里
- 错误的cv::face FacemarkLBF实例化
- C++的解析器在可以区分比较和模板实例化之前会做什么?
- 为什么 gcc 和 clang 为函数模板的实例化生成不同的符号名称?
- 检查某些类型是否是模板类 std::optional 的实例化
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 模板化类构造函数的模板实例化
- 在 c++ 中的模板实例化中使用带有构造函数的类作为类型参数
- 受约束的成员函数和显式模板实例化
- 对显式实例化的模板函数的未定义引用
- 如何"reject"实例化类