webentwicklung-frage-antwort-db.com.de

Können wir einen Klassenkopienkonstruktor in C++ virtuell machen?

Können wir einen Klassenkopienkonstruktor in C++ virtuell machen? Wie benutzt man?

24
user1295465

Nein, das können Sie nicht, Konstruktoren können nicht virtuell sein.

C++ 03 - 12.1 Konstruktoren  

4) Ein Konstruktor darf nicht virtual (10.3) oder static (9.4) sein. [...]

Wenn Sie so etwas benötigen, können Sie das virtuelle Konstruktor-Idiom hier nachschlagen.

22
Luchian Grigore

Nein, du kannst nicht.

Darüber hinaus ergibt das gesamte Konzept keinen Sinn. Virtuelle Funktionen sind Funktionen, die basierend auf dem Wert eines Objekts (dem dynamischen Typ des Objekts) ausgelöst werden. Wenn ein Konstruktor aufgerufen wird, hat das Objekt noch keinen Wert (weil es noch nicht erstellt wurde). Daher kann möglicherweise kein virtueller Versand erfolgen.

Denk darüber nach. Welche Semantik hätte ein solcher Konstruktor?

4
Mankarse

Nein. Da C++ eine statische Sprache ist, ist es für den C++ - Compiler nicht sinnvoll, ein Objekt polymorph zu erstellen. Der Compiler muss den Klassentyp kennen, um das Objekt zu erstellen. Mit anderen Worten, der zu erstellende Objekttyp ist eine Compilerzeitentscheidung aus der Perspektive des C++ - Compilers. Wenn wir Konstruktor virtuell machen, kennzeichnet der Compiler einen Fehler. 

1
zsounder

Dies ist nicht möglich, da der Speicher zugewiesen wird, bevor der Konstruktor basierend auf der Größe des neuen Typs und nicht des Kopieroperanden aufgerufen wird. Und wenn es funktioniert hat, wäre es ein Sonderfall, dass der Polymorphismus für eine Reihe von Sprachkonstrukten umgekehrt wurde.

Das bedeutet jedoch nicht, dass es nicht mit ein wenig C++ - Zauber möglich ist. :)

Es gibt einige Fälle, in denen dies unglaublich hilfreich ist, beispielsweise das Serialisieren von Nicht-POD-Klassen. In diesem Beispiel wird ein Konstruktor für virtuelle Kopien erstellt, der mit der Platzierung neu funktioniert. 

Warnung: Dies ist ein Beispiel, das einigen Benutzern bei bestimmten Problemen helfen kann. Tun Sie dies nicht im Allzweckcode. Es wird abstürzen, wenn der für die neue Klasse zugewiesene Speicher kleiner als die abgeleitete Klasse ist. Die beste (und einzige) sichere Möglichkeit, dies zu verwenden, besteht darin, Ihren eigenen Klassenspeicher zu verwalten und die neue Platzierung zu verwenden.

class VirtualBase
{
public: 
    VirtualBase() {}
    virtual ~VirtualBase() {}

    VirtualBase(const VirtualBase& copy)
    {
        copy.VirtualPlacementCopyConstructor(this);
    }

    virtual void VirtualPlacementCopyConstructor(void*) const {}
};

class Derived :: public VirtualBase
{
public:
    ...

    Derived(const Derived& copy) : ... don't call baseclass and make an infinite loop
    {
    }

protected:
    void VirtualPlacementCopyConstructor(void* place) const
    {
        new (place) Derived(*this);
    }
};
1
George Davison

Niemals ist es in C++ nicht möglich.

0
user1251300

Ja, Sie können einen Konstruktor für virtuelle Kopien erstellen, aber keinen virtuellen Konstruktor.

Grund:

Virtueller Konstruktor: - Nicht möglich, da es sich bei c ++ um eine statische Typsprache und einen Konstruktor als virtuelles Objekt handelt, sodass der Compiler nicht entscheiden kann, welcher Objekttyp es ist, und der gesamte Prozess aufgrund des virtuellen Schlüsselworts zur Laufzeit bleibt. Der Compiler muss den Klassentyp kennen, um das Objekt zu erstellen. Mit anderen Worten, der zu erstellende Objekttyp ist eine Compilerzeitentscheidung aus der Perspektive des C++ - Compilers. Wenn wir Konstruktor virtuell machen, kennzeichnet der Compiler einen Fehler.

Konstruktor für virtuelle Kopien: - Ja Möglich, Anwendung der Zwischenablage berücksichtigen. Ein Clipboard kann verschiedene Arten von Objekten enthalten und Objekte aus vorhandenen Objekten kopieren und auf der Anwendungsleinwand einfügen. Auch hier ist der Typ des zu kopierenden Objekts eine Laufzeitentscheidung. Der virtuelle Kopierkonstruktor füllt hier die Lücke. 

0
Priyanka Soni