Подтвердить что ты не робот

Как клонировать объект в С++? Или есть другое решение?

Я написал реализацию Stack и Queue (основанный на Linked List). Существует один стек (bigStack). Например, я разделяю bigStack (пример: stackA и stackB). я pop() a node от bigStack, я push() в stackA. Точно так же я push() в stackB. Я хочу, чтобы bigStack не изменился. Поэтому я хочу клонировать объект bigStack. Как клонировать объекты на С++? Или есть другое решение моей проблемы?

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

};

то...

Stack copyStack = veriYapilariDersi;
copyStack.DisplayStack();
4b9b3361

Ответ 1

Типичным решением для этого является создание собственной функции для клонирования объекта. Если вы можете предоставить конструкторы копирования и операторы присваивания копий, это может быть настолько далеко, насколько вам нужно.

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

Иногда полезно предоставить явный метод clone(), особенно для полиморфных классов.

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: Поскольку Stack не имеет переменных-членов, в конструкторе копирования или операторе присваивания копии ничего не нужно делать для инициализации членов Stack из так называемой "правой стороны" (rhs). Тем не менее, вам все равно необходимо обеспечить, чтобы любому базовому классу была предоставлена ​​возможность инициализировать своих членов.

Вы делаете это, вызывая базовый класс:

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

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

Ответ 2

В C++ копирование объекта означает клонирование. Никакого специального клонирования в языке нет.

Как предполагает стандарт, после копирования у вас должно быть 2 идентичных копии одного и того же объекта.

Существует 2 типа копирования: конструктор копирования при создании объекта в неинициализированном пространстве и оператор копирования, в котором необходимо сбросить старое состояние объекта (которое должно быть действительным) перед установкой нового состояния.

Ответ 3

Если ваш объект не является полиморфным (и, вероятно, реализация стека нет), то, как и в других ответах, вам нужен конструктор копирования. Обратите внимание, что существуют различия между созданием копии и назначением в C++; если вы хотите, чтобы оба поведения (и версии по умолчанию не соответствовали вашим потребностям), вам придется реализовать обе функции.

Если ваш объект полиморфный, то нарезка может быть проблемой, и вам, возможно, придется перепрыгнуть через некоторые дополнительные обручи, чтобы сделать правильное копирование. Иногда люди используют в качестве виртуального метода clone() в качестве помощника для полиморфного копирования.

Наконец, обратите внимание, что получить правильное копирование и назначение, если вам нужно заменить версии по умолчанию, на самом деле довольно сложно. Обычно лучше настроить ваши объекты (через RAII) таким образом, чтобы версии копирования/назначения по умолчанию делали то, что вы от них хотите. Я настоятельно рекомендую вам взглянуть на Meyer Effective C++, особенно на пункты 10,11,12.