Как создать разные дочерние классы условно? - PullRequest
7 голосов
/ 27 февраля 2012

Например, в основной функции я хочу получить ввод пользователя.В зависимости от ввода я создам Rectangle или Circle, которые являются дочерними классами 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, он все же прошел через него.

Так, как я должен поместить экземпляры Objects как дочерние классы в некоторые операторы if ??

1 Ответ

10 голосов
/ 27 февраля 2012

Вы можете создавать автоматические объекты в операторах if, но они будут уничтожены в конце области, в которой они созданы, поэтому они не будут работать для этой проблемы.

Причина, по которой вы не можете сделать obj = Rectangle(), заключается в том, что нарезка .

У вас должен быть указатель на Object.Указатели на базовые объекты также могут указывать на экземпляры дочерних объектов.Затем вы можете динамически создать объект внутри if с помощью new (объекты, созданные с 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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...