2009-09-28 22 views
10

Supposons que je donne les résultats suivants (cas simplifié):constructeur Copie: copie en profondeur une classe abstraite

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); 
} 

Maintenant, est-il un moyen pour moi de faire une copie profonde de la IColor abstraite dans le constructeur de copie Matériel? C'est-à-dire que je veux que les valeurs de m._color soient copiées (une couleur, une texture) et pas seulement le pointeur vers IColor.

Répondre

7

Vous pouvez ajouter une fonction clone() à votre interface.

1

Vous devrez ajouter ce code vous-même au constructeur de copie Material. Ensuite, codez pour libérer l'IColor alloué dans votre destructeur.

Vous devrez également ajouter un destructeur virtuel à IColor. La seule façon de faire une copie profonde serait de stocker une couleur directement à la place d'un pointeur vers un IColor.

+0

Pourquoi? –

+0

Parce que, par défaut, il copiera simplement l'adresse du pointeur dans l'adresse du pointeur copié. Il ne copiera pas ce qui est pointé et réajustera le pointeur. Luke a la meilleure suggestion pour créer une fonction clone() appelée depuis le constructeur de la copie. –

0

Ajout d'une méthode de couleur est probablement le meilleur clone(), mais si vous ne possédez pas cette option, une autre solution serait d'utiliser dynamic_cast pour lancer IColor * à * Couleur. Vous pouvez ensuite appeler le constructeur de copie de couleur. Pourquoi le stockage d'un pointeur sur IColor désactivera-t-il la copie profonde?

+0

Mais vous ne savez pas si c'est une couleur ou une texture, comment pouvez-vous dynamic_cast alors? – Barth

+0

Si l'objet n'est pas de type, alors dynamic_cast (_color) retournera null. (La distribution dynamique/rtti peut détecter le type réel tant que la classe a au moins une méthode virtuelle). Donc, ce que vous pouvez faire est de tester les possibilités. Ce n'est pas amusant, et presque toujours pire que d'utiliser une méthode clone(), mais il y a des situations rares où vous devez faire quelque chose comme ça. –

Questions connexes