web-dev-qa-db-ja.com

C ++でオブジェクトを複製する方法は?または別の解決策はありますか?

スタックとキューの実装(リンクリストベース)を作成しました。 1つのスタック(bigStack)があります。たとえば、bigStack(例:stackAstackB)を分離します。 I pop()bigStackからのノード、I Push() in stackA。同様に、stackBPush()も同様です。 bigStackが変更されないようにします。したがって、bigStackオブジェクトのクローンを作成します。 C++でオブジェクトを複製するにはどうすればよいですか?または、私の問題の別の解決策はありますか?

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();
23
mert

これに対する一般的な解決策は、オブジェクトを複製する独自の関数を作成することです。コピーコンストラクタとコピー代入演算子を提供できる場合、これは必要な範囲で実行できます。

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

編集:Stackにはメンバー変数がないため、コピーコンストラクターまたはコピー代入演算子では、Stackのメンバーをいわゆる「右側」(rhs)。ただし、基本クラスにtheirメンバーを初期化する機会を与える必要があります。

これを行うには、基本クラスを呼び出します。

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

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

オブジェクトがポリモーフィックでない(そしてスタック実装がそうでない可能性が高い)場合、ここでの他の回答に従って、必要なのはコピーコンストラクターです。 C++のコピーの構築と割り当てには違いがあることに注意してください。両方の動作が必要な場合(およびデフォルトバージョンがニーズに合わない場合)、両方の機能を実装する必要があります。

オブジェクトがポリモーフィックである場合、スライシングが問題になる可能性があり、適切なコピーを行うために余分なフープをジャンプする必要がある場合があります。時々、人々は多相コピーのヘルパーとしてclone()と呼ばれる仮想メソッドとして使用します。

最後に、デフォルトバージョンを置き換える必要がある場合、コピーと割り当てを正しく行うことは実際には非常に難しいことに注意してください。通常、コピー/割り当てのデフォルトバージョンが目的の動作を行うように、オブジェクトを(RAIIを介して)設定することをお勧めします。 Meyer's Effective C++ 、特にアイテム10,11,12をご覧になることを強くお勧めします。

3
WeirdlyCheezy

C++では、オブジェクトのコピーとは複製を意味します。この言語には特別なクローンはありません。

標準が示唆しているように、コピー後、同じオブジェクトの2つの同一のコピーが必要です。

コピーには2つのタイプがあります。初期化されていないスペースでオブジェクトを作成する場合のコンストラクターと、新しい状態を設定する前にオブジェクトの古い状態(有効であると予想される)を解放する必要があるコピー演算子です。

3
Kirill Kobelev