web-dev-qa-db-fra.com

Comment cloner un objet en C++? Ou y a-t-il une autre solution?

J'ai écrit une implémentation Stack and Queue (basée sur une liste liée). Il y a une pile (bigStack). Par exemple, je sépare bigStack (exemple: stackA et stackB). I pop() un noeud de bigStack, I Push() in stackA. De la même manière, je Push() dans stackB. Je veux que bigStack ne change pas. Par conséquent, je veux cloner l'objet bigStack. Comment cloner des objets en C++? Ou y a-t-il une autre solution à mon problème?

class Stack : public List {
public:
   Stack() {}
   Stack(const Stack& rhs) {}
   Stack& operator=(const Stack& rhs) {};
    ~Stack() {}

    int Top() {
        if (head == NULL) {
            cout << "Error: The stack is empty." << endl;
            return -1;
        } else {
            return head->nosu;
        }
    }

    void Push(int nosu, string adi, string soyadi, string bolumu) {
        InsertNode(0, nosu, adi, soyadi, bolumu);
    }

    int Pop() {
        if (head == NULL) {
            cout << "Error: The stack is empty." << endl;
            return -1;
        } else {
            int val = head->nosu;
            DeleteNode(val);
            return val;
        }
    }

    void DisplayStack(void);

};

puis...

Stack copyStack = veriYapilariDersi;
copyStack.DisplayStack();
23
mert

La solution typique à cela est d'écrire votre propre fonction pour cloner un objet. Si vous êtes en mesure de fournir des constructeurs de copie et des opérateurs d’assignation de copie, il se peut que ce soit tout ce dont vous avez besoin.

class Foo
{ 
public:
  Foo();
  Foo(const Foo& rhs) { /* copy construction from rhs*/ }
  Foo& operator=(const Foo& rhs) {};
};

// ...

Foo orig;
Foo copy = orig;  // clones orig if implemented correctly

Parfois, il est avantageux de fournir une méthode clone() explicite, en particulier pour les classes polymorphes.

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

class Foo : public Interface
{
public:
  Interface* clone() const { return new Foo(*this); }
};

class Bar : public Interface
{
public:
  Interface* clone() const { return new Bar(*this); }
};


Interface* my_foo = /* somehow construct either a Foo or a Bar */;
Interface* copy = my_foo->clone();

EDIT: Puisque Stack n'a pas de variable de membre, il n'y a rien à faire dans le constructeur de copie ou l'opérateur d'affectation de copie pour initialiser les membres de Stack à partir du "côté droit" (rhs). Cependant, vous devez toujours vous assurer que les classes de base ont la possibilité d'initialiser leurs membres.

Vous faites cela en appelant la classe de base:

Stack(const Stack& rhs) 
: List(rhs)  // calls copy ctor of List class
{
}

Stack& operator=(const Stack& rhs) 
{
  List::operator=(rhs);
  return * this;
};
28
John Dibling

Si votre objet n'est pas polymorphe (et qu'une implémentation de pile ne le soit probablement pas), alors, comme indiqué dans les autres réponses fournies ici, vous voulez un constructeur de copie. Veuillez noter qu'il existe des différences entre la construction de copie et l'affectation en C++; Si vous voulez les deux comportements (et que les versions par défaut ne répondent pas à vos besoins), vous devrez implémenter les deux fonctions.

Si votre objet est polymorphe, le découpage en tranches peut poser problème et vous devrez peut-être effectuer des opérations supplémentaires pour effectuer une copie correcte. Parfois, des personnes utilisent comme méthode virtuelle appelée clone () un assistant pour la copie polymorphe.

Enfin, notez que, si vous devez remplacer les versions par défaut, il est en fait assez difficile d’obtenir une copie et une affectation correctes. Il est généralement préférable de configurer vos objets (via RAII) de manière à ce que les versions par défaut de copier/assigner fassent ce que vous voulez. Je vous recommande vivement de consulter Effective C++ de Meyer, en particulier les points 10,11,12.

2
WeirdlyCheezy

En C++, copier l'objet signifie cloner. Il n'y a pas de clonage spécial là-bas.

Comme le standard le suggère, après la copie, vous devez disposer de 2 copies identiques du même objet.

Il existe 2 types de copie: le constructeur de copie lorsque vous créez un objet sur un espace non initialisé et l'opérateur de copie où vous devez libérer l'ancien état de l'objet avant de définir le nouvel état.

2
Kirill Kobelev