30

スタックとキューの実装(リンクリストベース)を作成しました。スタックが1つあります(bigStack)。たとえば、私は分離しますbigStack(例:stackAstackB)。私pop()はからのノードbigStack、私push()stackA。同じように、私push()stackB。変わらない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();
4

3 に答える 3

39

これに対する一般的な解決策は、オブジェクトのクローンを作成するための独自の関数を作成することです。コピーコンストラクターとコピー割り当て演算子を提供できる場合、これは必要な範囲である可能性があります。

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)からのメンバーを初期化することは何もありません。ただし、基本クラスにメンバーを初期化する機会が与えられていることを確認する必要があります。

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

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

Stack& operator=(const Stack& rhs) 
{
  List::operator=(rhs);
  return * this;
};
于 2012-10-15T19:42:34.723 に答える
2

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

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

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

于 2012-10-15T19:42:50.207 に答える
2

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

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

最後に、デフォルトバージョンを置き換える必要がある場合、コピーと割り当てを正しく行うことは実際には非常に難しいことに注意してください。通常、デフォルトバージョンのコピー/割り当てでオブジェクトが実行したいことを実行するように(RAIIを介して)オブジェクトを設定することをお勧めします。MeyerのEffectiveC++、特に項目10、11、12を確認することを強くお勧めします。

于 2012-10-15T20:15:58.110 に答える