0

ある派生クラスのオブジェクトを別のオブジェクトのプロパティとして保存したいと思います。

私にとっての問題は、格納されるオブジェクトのサイズを知ることです。これは、特定の基本クラスの任意の派生クラスである可能性があるためです。基本クラスのオブジェクトは小さいので、メモリを割り当てることはできません。typeof演算子も基本クラスのサイズを与えるだけだと思いますよね?

これが私のサンプルコードです。コメントを見て、私が何を意味するのかを理解してください。独創性がないので失礼します…</p>

BaseA {};

DerivedA1 : BaseA {public: void property() { cout << 1; }};
DerivedA2 : BaseA {public: void property() { cout << 2; }};
// etc. - several derived classes.

BaseB   // Contains (or links to) an instance of class derived from BaseA.
{
public:
    BaseA * instanceA;

    BaseB (BaseA instanceAX)
    {
        // ??? => How to allocate memory for the object
        // I don't know the real type of?
        instanceA = new BaseA (instanceAX);
    }

    BaseB (BaseA instanceAX) { delete instanceA; }
};

main()
{
    DerivedA1 instanceA1;
    BaseB instanceB (instanceA1);

    // Use "property" regardless of which derived class it belongs to.
    instanceB.instanceA->property();
} 

オブジェクト自体の代わりにポインタを格納することもできます。しかし、インスタンスinstanceBの存続期間中、プロパティオブジェクトを保持するために呼び出し元に依存したいかどうかはわかりません。

ありがとう!

4

2 に答える 2

3

まず第一に、BaseAは参照やポインターではなく値で渡すので、タイプを知っています。BaseAです。BaseBがBaseAにコピーされ、そのBaseAコピーが関数に送信されます。BaseBの追加データはinstanceAXに含まれていません。これは「スライス」と呼ばれます。

しかし、あなたの質問に答えるために、あなたは単にこのようにそれをしません。このように機能するように意図されている場合は、BaseBクラスにclone()関数が必要です。または、インスタンスのクローンを作成できるスマートポインタまたはその他のオブジェクトを設計することもできます。comp.lang.c ++でclone()と一緒に私の名前を検索すると、この後者のアイデアについて私がそこで行った議論に出くわすかもしれません。

クローン関数はもちろん、現在のオブジェクトのコピーを返す仮想関数です。

struct BaseA
{
  virtual BaseA* clone() const = 0;
};

struct BaseB : BaseA
{
  BaseB* clone() const { return new BaseB(*this); }
};
于 2010-11-28T21:56:53.673 に答える
2

2つの可能性があります。

  • 呼び出されたインスタンスのコピーを生成する役割を担うBaseA、純粋仮想メンバー関数(と呼ばれることもあります)を提供します。clone次に、のコンストラクタBaseB

    BaseB (BaseA const &instanceAX) { instanceA = instanceAX.clone (); }

  • また、生のポインタを渡すことを避けて、boost::shared_ptr代わりに使用することもできます。このように、参照カウントされるため、呼び出し元は、のBaseA作成に使用された派生の早期破壊を引き起こすことはできませんBaseB。Thenのコンストラクターは次のようになりBaseA * instanceA;ます。boost::shared_ptr <BaseA> instanceA;BaseB

    BaseB (boost::shared_ptr <BaseA> a) : instanceA (a) { }

最初のアプローチの問題は、たとえば、から継承する一部のクライアントプログラマーが、自分の派生でDerivedA1実装するのを忘れる可能性があることです。clone2番目のアプローチの主な問題は、すべてのユーザーにプロパティオブジェクトをヒープに割り当てるように要求することですBaseB(とにかくコンストラクター内でコピーを作成しているためBaseB、少なくとも合計メモリ消費量は増加しません)

于 2010-11-28T22:00:10.203 に答える