2012-05-14 13 views
5

Mam następującą relację klas. Chcę sklonować klasę pochodną, ​​ale pojawia się błąd "nie można utworzyć instancji klasy abstrakcyjnej". Jak mogę sklonować klasę pochodną? Dzięki.Klonowanie klasy C++ metodami czysto wirtualnymi

class Base { 
public: 
    virtual ~Base() {} 
    virtual Base* clone() const = 0; 
}; 

class Derived: public Base { 
public: 
    virtual void func() = 0; 
    virtual Derived* clone() const { 
     return new Derived(*this); 
    } 
}; 
+0

Co by to zrobiło? Klon jest zasadniczo operacją na poziomie obiektu. Bez konkretnego obiektu, skąd wiesz, co sklonować? – Joe

Odpowiedz

2

Tylko klasa betonu może być instancied. Func nie powinien być czysty.

4

Nie można instancję klasy, która ma czystą funkcję wirtualną tak:

virtual void yourFunction() = 0 

dokonać podklasy lub usunąć.

+0

lub podaj implementację – obmarg

6

Można tworzyć tylko konkretne klasy. Musisz przeprojektować interfejs programu pochodnego w celu przeprowadzenia klonowania. Najpierw usuń virtual void func() = 0; Wtedy będzie można napisać ten kod:

class Base { 
public: 
    virtual ~Base() {} 
    virtual Base* clone() const = 0; 
}; 

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

Innym rozwiązaniem jest utrzymywanie czystego funkcji wirtualnych w miejscu i dodając konkretną klasę:

class Base { 
public: 
    virtual ~Base() {} 
    virtual Base* clone() const = 0; 
}; 

class Derived: public Base { 
public: 
    virtual void func() = 0; 
}; 

class Derived2: public Derived { 
public: 
    virtual void func() {}; 
    virtual Derived2* clone() const { 
     return new Derived2(*this); 
    } 
}; 
0

I można powiedzieć coś głupiego tutaj, ale Myślę, że metoda klon w klasie pochodnej powinna nadal zwracać wskaźnik do klasy bazowej. Być może nadal kompiluje się dobrze, ale jeśli chodzi o łatwość obsługi kodu, myślę, że lepiej jest użyć metody klon tylko do zwracania wskaźników do klasy bazowej. Po tym wszystkim, jeśli klasa pochodna musi sklonować do wskaźnika do klasy pochodnej, można równie dobrze zrobić

Derived original; 
Derived* copy = new Derived(original) 

Oczywiście, trzeba zaimplementować konstruktor kopiujący, ale które powinny być z reguły realizowane w każdym razie (z wyjątkiem ekstremalnych przypadków).