2017-09-21 4 views
3

Ich habe eine Frage zum Kopieren von polymorphen Objekten. Mein Ausgangspunkt ist das übliche Beispiel dafür, wie ein Klon-Funktion zu implementieren:Kopieren von polymorphen Objekten

#include <iostream> 

class Base 
{ 
    protected: 
    int a; 

    public: 
    void set_a(int x) { a = x; } 
    void get_a() { std::cout << a << "\n"; } 
    virtual ~Base() {} 

    virtual Base *clone() const = 0; 
}; 

class Derived : public Base 
{ 
    public: 
    virtual Derived *clone() const 
    { 
     return new Derived(*this); 
    } 
}; 

int main(int argc, char *argv[]) 
{ 
    Base *ptr = new Derived; 
    ptr->set_a(20); 
    ptr->get_a(); 

    Base *cpy = ptr->clone(); 
    cpy->get_a(); 
} 

Warum die Linie new Derived(*this) Ergebnis in einem Kopier von this? Liegt es daran, dass wir den Kopierkonstruktor Derived mit this als Argument aufrufen?

Wenn wir in der Tat sind die Copykonstruktor von Derived aufrufen, warum dann nicht die folgenden kompilieren:

Base *b = new Derived(ptr); //does not compile 
+2

'ptr' ist vom Typ' Base * ', warum sollte' new Derived (ptr); 'kompilieren? – songyuanyao

+2

Ein Kopierkonstruktor kopiert per Definition eine Instanz der gleichen Klasse. 'ptr' ist keine Instanz derselben Klasse. –

Antwort

4

Ist es, weil wir den Kopierkonstruktor von Derived nennen?

Absolut. *this Ausdruck innerhalb Derived::clone ist vom Typ Derived&, so Derived::Derived(const Derived& original) Kopie Konstruktor heißt.

Warum funktioniert die folgende Kompilierung:

Base *b = new Derived(ptr); 

Dieser Aufruf nicht kompilieren, weil ptr ein Zeiger ist, keine Referenz. Dies würde kompilieren, aber es wäre im Rahmen des Klonens sinnlos:

Base *b = new Derived(*ptr); 

Der Punkt des Klonens ist, dass Sie nicht wissen, welche Art Sie als Ergebnis erhalten; Wenn Sie new Derived(*ptr) tun, geben Sie den Typ explizit an.

Verwandte Themen