Виртуальные Конструкторы - PullRequest
       43

Виртуальные Конструкторы

3 голосов
/ 16 сентября 2008

Нужны ли виртуальные конструкторы? Если да, то может ли кто-нибудь опубликовать сценарий?

Ответы [ 9 ]

8 голосов
/ 16 сентября 2008

Если вы говорите о виртуальных деструкторах в C ++ (виртуальных конструкторов не существует), то их всегда следует использовать, если вы используете полиморфно дочерние классы.

class A
{
  ~A();
}

class B : public A
{
  ~B();
}

A* pB = new B();
delete pB; // NOTE: WILL NOT CALL B's destructor

class A
{
  virtual ~A();
}

class B : public A
{
  virtual ~B();
}

A* pB = new B();
delete pB; // NOTE: WILL CALL B's destructor

Редактировать: Не уверен, почему у меня есть пониженное голосование за это (было бы полезно, если вы оставили комментарий ...), но также прочитайте здесь

http://blogs.msdn.com/oldnewthing/archive/2004/05/07/127826.aspx

3 голосов
/ 16 сентября 2008

Как всегда: посмотрите на C ++ FAQ Lite: виртуальные функции .

Он объяснит не только "виртуальный конструктор", но и деструкторы / функции!

Это, конечно, если вы в первую очередь хотели C ++ ...

2 голосов
/ 16 сентября 2008

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

2 голосов
/ 16 сентября 2008

Delphi - это один язык, который поддерживает виртуальные конструкторы.

Обычно они используются в сценарии типа фабрики классов, где вы создаете метатип, то есть тип, который описывает тип. Затем вы будете использовать этот мета-тип для построения конкретного примера вашего потомка класса

Код будет что-то вроде ....

type
  MyMetaTypeRef = class of MyBaseClass;

var
  theRef : MyMetaTypeRef;
  inst : MyBaseClass;
begin 
  theRef := GetTheMetaTypeFromAFactory(); 
  inst := theRef.Create(); // Use polymorphic behaviour to create the class
1 голос
/ 16 сентября 2008

На каком языке? Например, в C ++ конструкторы не могут быть виртуальными.

0 голосов
/ 20 февраля 2013

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

0 голосов
/ 26 июля 2012

В C ++ все конструкторы неявно виртуальны (с небольшим дополнительным). То есть конструктор базового класса вызывается раньше, чем конструктор производного класса. Так что они вроде виртуальные. Потому что в виртуальном методе, если производный класс реализует метод с той же сигнатурой, вызывается только метод в производном классе.

Тем не менее, в конструкторе, ОБЫКНОВЕНЫ ОБОСНОВАННЫЕ МЕТОДЫ (см. Пример ниже).

Более полное объяснение, почему это так, см. В пункте 9 «Эффективного C ++», третье издание, Скотта Мейерса (Никогда не вызывайте виртуальную функцию во время строительства или разрушения). Название вопроса может вводить в заблуждение относительно вопроса, но если вы прочитаете объяснение, это будет иметь смысл.

#include <iostream>
#include <vector>

class Animal {

    public:

        Animal(){
            std::cout << "Animal Constructor Invoked." << std::endl;
        }

        virtual void eat() {
            std::cout << "I eat like a generic animal.\n";
        }

        //always make destructors virtual in base classes
        virtual ~Animal() {

        }

};

class Wolf : public Animal {

    public:

        Wolf(){
            std::cout << "Wolf Constructor Invoked." << std::endl;
        }

        void eat() {
            std::cout << "I eat like a wolf!" << std::endl;
        }

};


int main() {

    Wolf wolf;
    std::cout << "-------------" << std::endl;
    wolf.eat();

}

Выход:

Animal Constructor Invoked.
Wolf Constructor Invoked.
-------------
I eat like a wolf!
0 голосов
/ 16 сентября 2008

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

Это также означает, что, несмотря ни на что, вам нужно знать, каким будет ваш объект. Однако то, что вы можете сделать, выглядит примерно так:

Superclass *object = NULL;
if (condition) {
    object = new Subclass1();
}
else {
    object = new Subclass2();
}
object.setMeUp(args);

... иметь виртуальную функцию и вызывать ее после конструирования. Это стандартный шаблон в Objective-C, в котором сначала вы вызываете метод alloc для класса, чтобы получить экземпляр, а затем вызываете initilializer, который подходит вам.

Человек, который упомянул шаблон Abstract Factory, вероятно, более корректен для C ++ и Java.

0 голосов
/ 16 сентября 2008

Конструктор не может быть виртуальным по определению. Во время вызова конструктора объект еще не создан, поэтому полиморфизм не имеет никакого смысла.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...