Chaque objet doit en effet redéfinir Clone en modifiant simplement le type de l’objet créé de cette façon :
virtual ObjSPtr Clone() { return boost::shared_ptr<Object>(new LeTypeDeMonObjet(*this));}
Cela permet à GD de copier des objets sans en connaitre le type ( Copie d’objets polymorphes : cpp.developpez.com/faq/cpp/?page … LASS_clone ).
Les objets sont créés, avec donc le constructeur, principalement lorsqu’il sont insérés dans la liste des objets initiaux, lors du chargement de la scène. Ensuite, lorsqu’ils sont créés par une action, ou placés sur la scène, les objets sont copiés avec Clone() depuis la liste des objets initiaux.
C’est tout à fait normal : Le constructeur par copie généré automatiquement par le compilateur copie chaque membre de ta classe. Pour les pointeurs ( intelligents ou non ), il ne fait également que les copier, ce qui n’implique pas la copie de l’objet pointé.
Le constructeur par copie. ( Clone() est juste un artifice permettant de copier un objet sans connaitre son type. )
Il faut le réécrire de façon à ce qu’il copie tous les membres, et fasse également une copie de l’objet pointé par le pointeur intelligent. A noter que dans ce cas, il est également bon de redéfinir également l’opérateur d’assignement ( operator= ) car cet opérateur a un rôle similaire. Pour éviter de recopier deux fois le même code, on peut procéder avec une fonction Init :
[code]
class MyObject : public Object
{
public:
//…
/**
* Copy constructor.
*/
MyObject(const Object & object) : Object(object) //Ne pas oublier d'appeler le constructeur par copie de la classe de base !
{
Init(object);
};
/**
* Assignement operator.
*/
MyObject& operator=(const Object & object) {
Object::operator=(object); //Ne pas oublier d'appeler l'opérateur = de la classe de base !
if( (this) != &object )
Init(object);
return *this; }
private:
int monAttribut;
std::string maSuperVariable;
boost::shared_ptr<MonObjetComplique> monPointeurSurObjetComplique;
void Init(const MyObject & other);
}
void MyObject::Init(const MyObject & other)
{
monAttribut = other.monAttribut;
maSuperVariable = other.maSuperVariable;
monPointeurSurObjetComplique = boost::shared_ptr(new MonObjetComplique(*other.monPointeurSurObjetComplique)); //On ne contente pas de copier juste le pointeur, mais bien l’objet qui est pointé.
}[/code]
Il y a deux choses à faire gaffe :
-Ne pas oublier d’appeler le constructeur par copie/l’opérateur = de la classe de base : ( En effet, par défaut le compilateur fait ça pour nous, mais dès qu’on rédéfinit ces fonctions, il faut prendre gare à le faire si notre objet hérite d’un autre ).
-Ne pas oublier de mettre à jour Init() si l’on ajoute des membres à notre classe.
C’est le coté un peu ch*ant des classes qui ont des pointeurs.