2009-09-28 11 views
10

Załóżmy, że mam następujące (uproszczony przypadek):Kopiowanie konstruktor: głębokie kopiowanie klasę abstrakcyjną

class Color; 

class IColor 
{ 
public: 
    virtual Color getValue(const float u, const float v) const = 0; 
}; 

class Color : public IColor 
{ 
public: 
    float r,g,b; 
    Color(float ar, float ag, float ab) : r(ar), g(ag), b(ab) {} 
    Color getValue(const float u, const float v) const 
    { 
     return Color(r, g, b) 
    } 
} 

class Material 
{ 
private: 
    IColor* _color; 
public: 
    Material(); 
    Material(const Material& m); 
} 

Teraz jest jakiś sposób dla mnie zrobić głęboki kopię abstrakcyjne iColor w konstruktorze kopii z Materiał? To znaczy, chcę, aby wartości dowolnego koloru m._color (kolor, tekstura) były kopiowane, a nie tylko wskaźnik do IColor.

Odpowiedz

7

Możesz dodać funkcję clone() do swojego interfejsu.

1

Będziesz musiał sam dodać ten kod do konstruktora kopiowania materiałów. Następnie kodu, aby zwolnić przydzielone IColor w destruktora.

Będziesz także chciał dodać wirtualny destruktor do IColor.

Jedynym sposobem na wykonanie głębokiej kopii jest automatyczne zapisanie koloru bezpośrednio zamiast wskaźnika do koloru.

+0

Dlaczego przechowywanie wskaźnika na IColor spowoduje wyłączenie głębokiej kopii? –

+0

Ponieważ domyślnie po prostu skopiuje adres wskaźnika do skopiowanego adresu wskaźnika. Nie skopiuje tego, co jest wskazane, a następnie ponownie dostosuje wskaźnik. Luke ma najlepszą sugestię dotyczącą wywołania funkcji clone() z konstruktora kopiowania. –

0

wprowadzenie metody clone(), aby kolor jest chyba najlepszy, ale jeśli nie ma takiej możliwości, innym rozwiązaniem byłoby wykorzystanie dynamic_cast oddać do iColor * Kolor *. Następnie możesz wywołać konstruktor kopii kolorowej.

+0

Ale nie wiesz, czy to kolor czy tekstura, jak możesz wtedy dynamic_cast? – Barth

+0

Jeśli obiekt nie jest koloru, to dynamic_cast (_color) zwróci wartość null. (Dynamiczne rzutowanie/rtti może wykryć rzeczywisty typ, o ile klasa ma co najmniej jedną wirtualną metodę). Możesz więc sprawdzić możliwości. Nie jest to zabawne i prawie zawsze gorsze niż użycie metody clone(), ale są rzadkie sytuacje, w których trzeba zrobić coś takiego. –