2017-10-02 13 views
2

J'ai une classe SRecord et l'objet comme celui-ci en C++Comment prendre une sauvegarde/clone de l'objet en C++

SRecord* CurrentCmnd; 

CurrentCmnd = theStack->Pop(dig, operation1, resp_sol); 

Je voudrais sauvegarder le CurrentCmd ici

CurrentCmnd = theStack->Pop(dig, operation2, resp_sol); 

Après cette opération Je voudrais utiliser le CurrentCmnd qui revient de la première opération Pop afin que je puisse effectuer d'autres vérifications sur CurrentCmnd.

Comment puis-je faire une sauvegarde de CurrentCmnd ci-dessus avant de retirer le second élément de la pile.

Également vouloir mentionner que, je ne peux pas hériter de la classe SRecord, ne peut pas utiliser le constructeur de copie.

Je cherche la solution quelque chose comme ci-dessous

CurrentCmnd = theStack->Pop(dig, operation1, resp_sol); 

sauvegarde de CurrentCmnd.

SRecord* Temp_CurrentCmnd = CurrentCmnd; 

CurrentCmnd = theStack->Pop(dig, operation2, resp_sol); 

CurrentCmnd = Temp_CurrentCmnd; 

Répondre

2

Voici quelques moyens possibles pour y parvenir, toutes les méthodes supposent la classe a un constructeur de copie

simplement en utilisant un constructeur de copie

Vous pouvez simplement l'utiliser pour créer une copie -la mouche.

Création d'une copie allouée dynamiquement (ne pas oublier de libérer la mémoire une fois que vous avez fini avec elle):

SRecord * copy = new SRecord(*CurrentCmnd); 

Création d'une copie locale (cette volonté de copie existe seulement dans le cadre de la méthode) :

SRecord copy(*CurrentCmd); 

Ajout d'une méthode de clone à l'objet

une manière propre à mettre en œuvre cela est d'ajouter la fo méthode llowing à srecord:

class SRecord { 
    public: 
     SRecord * createBackup() { return new Object(*this); } 
} 

Alors vous pouvez simplement appeler:

SRecord * CurrentCmndBackup = CurrentCmnd->createBackup(); 

Ne pas oublier de libérer la sauvegarde lorsque vous avez terminé avec elle :)

mise en œuvre générique

Dans mes projets, j'ajoute généralement cette méthode à une classe de base dont je peux hériter plus tard. Il ressemble à ceci:

class Cloneable { 
    public: 
     virtual Cloneable * clone() = 0; 
} 

class SRecord : public Cloneable { 
    public: 
     virtual Cloneable * clone() { return new SRecord(*this); } 
} 

pointeur intelligent mise en œuvre

Une implémentation encore plus propre utilise des pointeurs intelligents.Dans la plupart de mes projets, j'ai trouvé que ces objets étaient quelque chose que je voudrais passer à d'autres modules, donc j'ai utilisé des pointeurs partagés, mais une implémentation de pointeur unique est également légitime.

Voici à quoi il ressemble:

class Cloneable { 
    public: 
     using Sptr = std::shared_ptr<Cloneable>; 
     virtual Sptr clone() = 0; 
}; 

class SRecord : public Cloneable { 
    public: 
     using Sptr = std::shared_ptr<SRecord>; 
     virtual Cloneable::Sptr clone() { return std::static_pointer_cast<Cloneable>(std::make_shared<SRecord>(*this)); } 
}; 

int main() 
{ 
    SRecord::Sptr a = std::make_shared<SRecord>(); 
    SRecord::Sptr b = std::static_pointer_cast<SRecord>(a->clone()); 
} 

mise en œuvre Templated

Comme suggéré, une mise en œuvre supplémentaire utilise une méthode de clone basé sur un modèle qui ne fait pas partie d'un objet:

template < typename T > 
std::shared_ptr<T> clone(const T & obj) { 
    return std::make_shared<T>(obj); 
} 
+0

Il serait plus sûr d'utiliser un 'std :: unique_ptr' ou un' std :: shared_ptr' comme valeur de retour de 'clone'. – owacoder

+0

@owacoder, j'ai ajouté une implémentation de pointeur intelligent, puisque je suis d'accord que c'est la bonne façon d'y aller :) –

+0

Je n'ai pas l'avantage de l'héritage ici, C++ n'est pas Java. Une solution basée sur un modèle serait plus naturelle à mon avis et tiendrait compte du code. – YSC