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

How to instantiate different child classes conditionally?

本文关键字:子类 实例化 有条件      更新时间:2023-10-16

例如,在主函数中,我想要获得用户的输入。根据输入,我将创建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语句中,我应该如何将实例化对象作为它的子类呢??

可以if语句中创建自动对象,但它们将在创建范围结束时被销毁,因此无法解决此问题。

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

你必须有一个指向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