1

<< 演算子をオーバーロードするようにいくつかのサブクラスを強制するための抽象基本クラスがあります。

これらのサブクラスのインスタンスへのポインターの束を std::stack に保存しています...ある時点で、スタックの一番上の項目を複製したい (そして一番上にプッシュしたい)。

問題は、抽象クラスをインスタンス化できないことです。明らかに、サブクラスごとにこれを実行したいので、型がわかりません...

これは、別の純粋な仮想メソッド (「Base *clone() = 0」など) を追加せずに可能であり、それを各サブクラスに実装するのだろうか? きっともっときれいな方法があるはずです。

4

2 に答える 2

4

この場合、実際にメソッドが必要だと思いますClone。実行時にサブクラス項目を動的にコピーする必要があり、実行時に動作を変更する通常の方法は仮想メソッドです。仮想メソッドを使用しないと、それがどの子であるかを把握する方法がありません。CRTPを使用して、そのクローンを自動的に生成することもできます。

// Totally uncompiled and untested.
class Base
{
public:
    virtual Base* Clone() const = 0;
};

template <class T>
class Child : public Base
{
public:
    virtual Base* Clone() const { return new T(*static_cast<T*>(this)); }
protected:
    Child(); // Can't instantiate directly
    Child(const Child& right); // Can't instantiate directly
};

class Grandchild : public Child<Grandchild>
{
    // Clone should do the right thing.
};
于 2011-02-02T05:25:35.853 に答える
0

ポインターを複製するのではなく、クラスのコピーを作成することを意味しますか。

独自のタイピングを実装する必要があります。言い換えれば、クラス型を返す仮想関数を持ち、適切なクラスを作成します

または、RTTI (Run-Time Type Information) を有効にして同じことを行います。RTTI はすべてのクラスに影響を与えるため、独自の typeof メソッドを作成する方が効率的である可能性があります。

その後、次のことができます

  1. ポインタをポップ
  2. タイプを取得する
  3. おそらくスイッチでコピーコンストラクターを使用して正しいクラスをインスタンス化します
  4. 両方をスタックに押し戻す

疑似コード

 base* ptr = stack.pop()
 base *copy
 switch (ptr->typeof()) {
  case class1type : copy = new class1(ptr) break;
  case class2type : copy = new class2(ptr) break;
  ...
}

stack.push (ptr)
stack.push(copy)

DC

于 2011-02-02T05:28:42.860 に答える