如何有条件地实例化不同的子类?

Posted

技术标签:

【中文标题】如何有条件地实例化不同的子类?【英文标题】:How to instantiate different child classes conditionally? 【发布时间】:2012-02-27 02:16:06 【问题描述】:

例如,在主函数中,我想获取用户的输入。根据输入,我将创建RectangleCircle,它们是Object 的子类。如果没有输入(或未知),那么我将创建一个通用对象。

class Object
 
       public:
           Object();
           void Draw();
       private:
           ....  
;
class Rectangle:public Object
 
       public:
           Rectangle();
           .... //it might have some additional functions
       private:
           ....  
;

class Circle:public Object
 
       public:
           Circle();
           .... //it might have some additional functions
       private:
           ....  
;

主要功能:

string objType;
getline(cin, objType);

if (!objType.compare("Rectangle"))
     Rectangle obj;
else if (!objType.compare("Circle"))
     Circle obj;
else 
     Object obj;

obj.Draw();

当然,上面的代码不起作用,因为我无法在 If 语句中实例化对象。所以我尝试了这样的事情。

Object obj;
if (!objType.compare("Rectangle"))
    obj = Rectangle();
else if (!objType.compare("Circle"))
    obj = Circle();


obj.Draw();

这段代码可以编译,但它不会做我想要的。由于某种原因,对象没有按照子类应有的方式启动(例如,我在子类中设置了一些对象的成员变量,特别是向量)。但是,当我在 Child 类构造函数处设置一个断点时,它确实运行到了那里。

那么我应该如何将实例化对象作为它的子类放在一些 if 语句中呢??

【问题讨论】:

【参考方案1】:

可以if 语句中创建自动对象,但它们将在创建它们的范围结束时被销毁,因此它们不适用于此问题。

你不能做obj = Rectangle()的原因是因为slicing。

您必须有一个指向Object 的指针。指向基础对象的指针也可以指向子对象的实例。然后,您可以使用newif 内动态创建对象(使用new 创建的对象忽略范围,并且仅在您在指向它们的指针上调用delete 时才被销毁),然后在您使用delete 时将其销毁重做:

Object* obj = NULL; // obj doesn't point to anything yet
string objType;
getline(cin, objType);

if (objType == "Rectangle")
    obj = new Rectangle; // make obj point to a dynamic Rectangle
else if (objType == "Circle")
    obj = new Circle; // make obj point to a dynamic Circle
else
    obj = new Object;  // make obj point to a dynamic Object

obj->Draw(); // draw whatever shape obj really points to

delete obj; // deallocate dynamic object

或者,您可以使用智能指针,然后您不必担心手动释放对象:

std::unique_ptr<Object> obj(NULL); // obj doesn't point to anything yet
string objType;
getline(cin, objType);

if (objType == "Rectangle")
    obj.reset(new Rectangle); // make obj point to a dynamic Rectangle
else if (objType == "Circle")
    obj.reset(new Circle); // make obj point to a dynamic Circle
else
    obj.reset(new Object);  // make obj point to a dynamic Object

obj->Draw(); // draw whatever shape obj really points to

// the unique_ptr takes care of delete'ing the object for us
// when it goes out of scope

【讨论】:

有效!除了我的问题的解决方案,感谢您对类和指针在 C++ 中的工作方式进行了很好的解释!

以上是关于如何有条件地实例化不同的子类?的主要内容,如果未能解决你的问题,请参考以下文章

创建型设计模式——工厂方法模式

J2SE之抽象类实例化

抽象方法真的不能实例化么?

当子类被实例化时,超类的私有成员是不是也被实例化? [复制]

设计模式最佳套路5 —— 愉快地使用工厂方法模式

JAVA-初步认识-第九章-继承-子父类中的构造函数-子类的实例化过程-细节