Могу ли я создать объект из производного класса, создав базовый объект с параметром?

Другими словами, для базового класса shape и производного класса rectangle:

class shape
{
public:
  enum shapeType {LINE, RECTANGLE};
  shape(shapeType type);
  shape(const shape &shp);
}

class rectangle : public shape
{
public:
  rectangle();
  rectangle(const rectangle &rec);
}

Я хотел бы знать, могу ли я создать экземпляр rectangle, вызвав:

shape *pRectangle = new shape(RECTANGLE);

и как я мог реализовать конструктор копирования, чтобы получить новый rectangle, вызвав:

shape *pNewRectangle = new shape(pRectangle);

person djeidot    schedule 09.07.2009    source источник


Ответы (6)


Краткий ответ: нет

Длинный ответ:

Вам нужен фабричный объект/метод.
Вы можете добавить статический фабричный метод к базовому классу, который создаст соответствующий тип объекта.

class Shape
{
    static Shape* createShape(shapeType type)
    {
        switch (type)
        {
             case RECTANGLE:return new rectangle();
           ...
        }
    }
 }; 

Личное предпочтение:

Я бы выбрал совершенно другой класс в качестве фабрики, а не использовал статический метод в базовом классе. Причина этого в том, что каждый раз, когда вы создаете новый класс Shape, указанный выше стиль вынуждает вас каждый раз перестраивать класс Shape.

Поэтому я бы разделил фабрику на класс ShapeFactory.

person Martin York    schedule 09.07.2009
comment
Почему класс? Я бы просто сделал фабричную функцию. - person Nemanja Trifunovic; 09.07.2009
comment
вот и все. И в соответствии с этим вопросом - stackoverflow.com/ вопросов/1021626/ - Думаю, мне также придется использовать метод Clone вместо конструктора копирования. - person djeidot; 09.07.2009
comment
В тривиальных случаях с фабричной функцией все в порядке. Но когда все становится сложнее и вам нужно разделить фабричный вызов на пару вызовов функций, с ограничениями доступности справиться намного проще, чем с несколькими статическими функциями. Но в данном случае это просто вопрос стиля. - person Martin York; 10.07.2009
comment
Когда все становится сложнее, если у вас есть класс, вы можете начать использовать абстрактные фабрики и, таким образом, возвращать разные типы объектов в зависимости от конфигурации времени выполнения. Таким образом, я мог бы иметь фабрику WindowShape и фабрику MacShapeFactory, основанную на простой абстрактной базовой фабрике. Опять же, вы можете сделать это с помощью функций, но это никогда не будет таким аккуратным. - person Martin York; 10.07.2009
comment
Клонирование так похоже на Java. Это просто заставляет меня дрожать. - person Martin York; 10.07.2009

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

Проблема в том, что когда вы делаете новую форму (...), вы всегда возвращаете экземпляр формы, а не прямоугольник. Если вам нужен «прямоугольник», в какой-то момент ему нужно будет вызвать новый прямоугольник (..). Метод может обрабатывать эту логику для вас, но не конструкцию по умолчанию в C++.

person Reed Copsey    schedule 09.07.2009

Вызов конструктора всегда даст вам объект типа конструктора.

new shape(...)

Я думаю, что вместо этого вы хотите использовать шаблон проектирования factory, где есть статический метод формы, который может создавать любой подтип по мере необходимости.

person Michael Donohue    schedule 09.07.2009

shape *pRectangle = new shape(RECTANGLE);

У вас нет возможности создать производный класс, создав базовый объект. Вы должны сделать новый производный класс.

person Naveen    schedule 09.07.2009

В C++ для этого можно использовать динамическое приведение типов, но, хм, нет, не из конструктора. Используйте его, как указано выше, в фабричном методе

см., например, http://www.cprogramming.com/reference/typecasting/dynamiccast.html< /а>

person Dave Archer    schedule 09.07.2009

Вы можете сделать что-то подобное с дизайном на основе политик. Ваш код будет примерно таким

shape* pRectangle = new derrivedType<rectangle>();

Проектирование на основе политик

person Chad Simpkins    schedule 09.07.2009