2008-09-16 13 views
3

Benötigen Sie virtuelle Konstruktoren? Wenn ja, kann jemand ein Szenario posten?Virtuelle Konstruktoren

+0

Sie müssen mehr Informationen zu dieser Frage hinzufügen - die Leute wissen nicht genau, wie man es beantwortet. –

+0

kann Konstruktor virtuell sein? Ich denke nicht ... wir können virtuellen Destruktor aber nicht virtuellen Konstruktor in C++ so weit haben. – rforritz

Antwort

1

In welcher Sprache? In C++ zum Beispiel können die Konstruktoren nicht virtuell sein.

3

Wie immer: Blick auf C++ FAQ lite: virtual functions.

Es wird nicht nur "virtueller Konstruktor", sondern auch Destruktoren/Funktionen erklären!

Dies natürlich, wenn Sie C++ in erster Linie wollte ...

0

Der Konstruktor kann per Definition nicht virtuell sein. Zum Zeitpunkt des Aufrufs des Konstruktors wurde noch kein Objekt erstellt, daher macht der Polymorphismus keinen Sinn.

+0

Das ist einfach nicht wahr. Konstruktion kann durchaus virtuell sein, die ganze Idee besteht darin, eine Variable vom Typ baseclass deklarieren und aus einer anderen konkreten Klasse konstruieren zu können. Delphi ist zum Beispiel eine Sprache, die virtuelle Konstruktoren erlaubt. –

8

Wenn Sie über virtuelle Destruktoren in C++ sprechen (es gibt keine virtuellen Konstruktoren), sollten sie immer verwendet werden, wenn Sie Ihre untergeordneten Klassen polymorph verwenden.

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: nicht sicher, warum ich ein downvote dafür haben (wäre hilfreich, wenn Sie einen Kommentar verfasst ...), aber haben eine auch hier lesen

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

+1

... wahrscheinlich abgelehnt, weil Ihre Antwort zwar korrekt ist, aber nichts mit der Frage zu tun hat. Nicht von mir, BTW ... – Roddy

+1

es scheint eine faire Antwort aus meiner Sicht. +1 –

2

Delphi ist eine Sprache, die virtuelle Konstruktoren unterstützt.

Normalerweise würden sie in einem Klassenfactory-Szenario verwendet werden, in dem Sie einen Meta-Typ erstellen, also einen Typ, der einen Typ beschreibt. Sie würden dann, dass Meta-Typ verwenden, um ein konkretes Beispiel für Ihre abgeleiteten Klasse wie

-Code etwas ....

zum Beispiel
type 
    MyMetaTypeRef = class of MyBaseClass; 

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

Es gibt viele Szenarien, wäre zu konstruieren, wenn Sie GUIs erstellen möchten für mehr als eine Umgebung. Nehmen wir an, Sie haben Klassen für Steuerelemente ("Widgets"), aber jede Umgebung verfügt über ein eigenes Widget. Es ist daher logisch, die Erstellung dieser Widgets für jede Umgebung abzuleiten. Der Weg dies zu tun (da, wie es nicht hilfreich herausgestellt wurde, Konstruktoren können in den meisten Sprachen nicht virtuell sein), ist die Verwendung eines abstract factory und das obige Beispiel ist das Standardbeispiel, das verwendet wird, um dieses Entwurfsmuster zu beschreiben.

+0

Konstruktoren können tatsächlich in Delphi virtuell sein. –

0

In C++ gibt es keinen Grund für Konstruktoren, jemals virtuell zu sein, weil sie statische Funktionen sind. Das bedeutet, dass sie statisch gebunden sind. Sie müssen also die Konstruktorfunktion identifizieren, die Sie aufrufen, um sie überhaupt aufzurufen. Es gibt keine Unsicherheit und nichts virtuelles darüber.

Dies bedeutet auch, dass, egal was, Sie die Klasse kennen müssen, die Ihr Objekt sein wird. Was Sie tun können, ist jedoch so etwas wie dieses:

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

... eine virtuelle Funktion haben und es nach constructon nennen. Dies ist ein Standardmuster in Objective-C, in dem Sie zunächst die "alloc" -Methode der Klasse aufrufen, um eine Instanz zu erhalten, und dann den Initializer aufrufen, der zu Ihrer Verwendung passt.

Die Person, die das Abstract Factory-Muster erwähnte, ist wahrscheinlich für C++ und Java jedoch korrekter.

+0

Pity C++ - Klassen sind keine Objekte .... ----------------- In C++ gibt es keinen Grund für Konstruktoren, jemals virtuell zu sein, – David

-1

In C++ sind alle Konstruktoren implizit virtuell (mit ein wenig mehr). Das heißt, der Konstruktor der Basisklasse wird vor dem der abgeleiteten Klasse aufgerufen. Es ist also so, als wären sie virtuell. Wenn in einer virtuellen Methode die abgeleitete Klasse eine Methode derselben Signatur implementiert, wird nur die Methode in der abgeleiteten Klasse aufgerufen.

Jedoch in einem Konstruktor, sind beide Methoden (siehe Beispiel unten) eingegangen.

Für eine vollständigere Erklärung, warum dies so ist, siehe Punkt 9 von Effective C++, dritte Ausgabe, von Scott Meyers (Niemals eine virtuelle Funktion während der Konstruktion oder Zerstörung aufrufen). Der Titel des Artikels mag in Bezug auf die Frage irreführend sein, aber wenn Sie die Erklärung lesen, wird es vollkommen Sinn machen.

#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(); 

} 

Ausgang:

Animal Constructor Invoked. 
Wolf Constructor Invoked. 
------------- 
I eat like a wolf! 
+0

"In C++, alle Konstrukteure sind implizit virtuell "- Ich bin neugierig, ob Sie mich auf irgendeine Literatur verweisen können, die dies ausdrückt. – Pradyot

+0

Wie oben erwähnt, umreißt Punkt 9 in Scott Meyers Buch dies und erklärt dies. Eine Ausnahme bilden virtuelle Basisklassen. In Abschnitt 15.2.4.1 von "Die Programmiersprache C++, Special Edition" von Bjarne Stroustrup finden Sie eine Beschreibung der virtuellen Basisklassen und wie "die Sprache sicherstellt, dass ein Konstruktor einer virtuellen Basis genau einmal aufgerufen wird". – Homer6

-1

Virtuelle Konstrukteuren nicht Sinn in C++ machen. Dies liegt daran, dass Konstruktoren in C++ keinen Rückgabewert haben. In einigen anderen Programmiersprachen ist dies nicht der Fall. In diesen Sprachen kann der Konstruktor direkt aufgerufen werden und der Konstruktor hat einen Rückgabewert. Dies macht sie nützlich beim Implementieren bestimmter Arten von Entwurfsmustern. In C++ ist dies jedoch nicht der Fall.

+0

Sie haben Recht, wenn Sie sagen, dass virtuelle Konstruktoren in C++ keinen Sinn ergeben. Aber es hat wahrscheinlich nichts mit Rückgabewerten zu tun. – Pradyot