2008-09-16 22 views
3

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

+0

Вам нужно добавить дополнительную информацию по этому вопросу - люди точно не знают, как ответить на него. – 2008-09-16 10:37:43

+0

Может ли конструктор быть виртуальным? я так не думаю .. мы можем иметь виртуальный деструктор, но не виртуальный конструктор в C++. – rforritz 2013-06-26 19:14:51

ответ

1

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

3

Как всегда: посмотрите на C++ FAQ lite: virtual functions.

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

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

0

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

+0

Это просто неправда. Конструкция, безусловно, может быть виртуальной, и вся идея состоит в том, чтобы объявить переменную типа baseclass и построить ее из другого конкретного класса. Delphi - это, например, один язык, который позволяет создавать виртуальные конструкторы. – 2008-09-16 23:08:50

8

Если вы говорите о виртуальных деструкторах в 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 

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

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

+1

... Вероятно, ничтожество, потому что ваш ответ, хотя и правильный, не связан с вопросом. Не через меня, BTW ... – Roddy 2008-10-26 10:54:56

+1

это, кажется, справедливый ответ с моей точки зрения. +1 – 2011-06-07 12:25:49

2

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

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

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

type 
    MyMetaTypeRef = class of MyBaseClass; 

var 
    theRef : MyMetaTypeRef; 
    inst : MyBaseClass; 
begin 
    theRef := GetTheMetaTypeFromAFactory(); 
    inst := theRef.Create(); // Use polymorphic behaviour to create the class 
2

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

+0

Конструкторы действительно могут быть виртуальными в Delphi. – 2008-09-16 09:26:37

0

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

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

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

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

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

+0

Pity C++ классы не являются объектами .... ----------------- В C++ нет причин, по которым конструкторы никогда не будут виртуальными, – David 2009-07-27 19:22:02

-1

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

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

Для более полного объяснения, почему это так, см. Пункт 9 эффективного C++, третье издание, Scott Meyers (Никогда не называйте виртуальную функцию во время строительства или разрушения). Название предмета может вводить в заблуждение относительно вопроса, но если вы прочтете объяснение, это будет иметь смысл.

#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! 
-1

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