0

オブジェクトの包含に複数のレベルがある場合(1 つのオブジェクトが、別のオブジェクトを定義およびインスタンス化する別のオブジェクトを定義およびインスタンス化する..)、オブジェクト変数および関数を含む上部にアクセスすることは可能ですか?

例:

    class CObjectOne
    {
    public:
       CObjectOne::CObjectOne() { Create(); };

       void Create();

       std::vector<ObjectTwo>vObejctsTwo;
       int nVariableOne;
    }
    bool CObjectOne::Create()
    {
       CObjectTwo ObjectTwo(this);
       vObjectsTwo.push_back(ObjectTwo);
    }

    class CObjectTwo
    {
     public:
       CObjectTwo::CObjectTwo(CObjectOne* pObject)
       {
        pObjectOne = pObject;
        Create();
       };

       void Create();
       CObjectOne* GetObjectOne(){return pObjectOne;};

       std::vector<CObjectTrhee>vObjectsTrhee;
       CObjectOne* pObjectOne;
       int nVariableTwo;
    }
    bool CObjectTwo::Create()
    {
       CObjectThree ObjectThree(this);
       vObjectsThree.push_back(ObjectThree);
    }

    class CObjectThree
    {
     public:
       CObjectThree::CObjectThree(CObjectTwo* pObject)
       {
        pObjectTwo = pObject;
        Create();
       };

       void Create();
       CObjectTwo* GetObjectTwo(){return pObjectTwo;};

       std::vector<CObjectsFour>vObjectsFour;
       CObjectTwo* pObjectTwo;
       int nVariableThree;
    }
    bool CObjectThree::Create()
    {
       CObjectFour ObjectFour(this);
       vObjectsFour.push_back(ObjectFour);
    }

main()
{
    CObjectOne myObject1;
}

CObjectThree内から、CObjectOnenVariableOneにアクセスする必要があるとします。私は次のようにしたいと思います:

int nValue = vObjectThree[index].GetObjectTwo()->GetObjectOne()->nVariable1;

しかし、アプリケーションをコンパイルして実行すると、Memory Access Violation エラーが発生します。

  • 上記のコードの何が問題になっていますか (これは例であり、スペルミスが含まれている可能性があります)。
  • オブジェクトを静的ではなく動的に作成する必要がありますか?
  • 含まれているオブジェクトから、含まれているオブジェクトに格納されている変数を取得する方法は他にありますか?
4

3 に答える 3

1

おそらく、すべてのオブジェクトが次のような共通のインターフェイスから継承できます。

class MyObject
{
public:
    virtual int getData() = 0;
}

その後、stl ライブラリの std::tree を使用して構造を構築できます。

于 2011-03-08T07:48:13.567 に答える
1

コンテナー オブジェクトを指すポインターを渡す場合、このポインターはバック ポインターと呼ばれることがあります。この手法は、ウィジェットがその親ウィジェットへのアクセスを必要とする可能性のある GUI ライブラリで常に使用されています。

そうは言っても、循環依存関係(コンテナーがコンテナーに依存し、コンテナーがコンテナーに依存するという意味での循環) を含まないより良い設計があるかどうかを自問する必要があります。

バック ポインター手法が機能するために、厳密にオブジェクトを動的に作成する必要はありません。スタックに割り当てられた (または静的に割り当てられた) オブジェクトのアドレスはいつでも取得できます。他の人がそのオブジェクトへのポインターを使用している間、そのオブジェクトの寿命が続く限り。しかし実際には、この手法は通常、動的に作成されたオブジェクトで使用されます。

バックポインタの代わりにバックリファレンスを使用することもできることに注意してください。


セグメンテーション違反の原因はわかっていると思います。ベクターがメモリを再割り当てすると (サイズが大きくなった結果として)、古いベクター要素のアドレスは無効になります。しかし、これらのオブジェクトの子 (および孫) は、バックポインタに古いアドレスを保持しています!

バックポインターが機能するには、各オブジェクトを動的に割り当て、それらのポインターをベクターに格納する必要があります。これにより、メモリ管理が非常に面倒になるため、スマート ポインターまたは boost::ptr_containers を使用することをお勧めします。


別の回答であなたが行ったコメントを見た後、あなたが達成しようとしていることをよりよく理解できました。一般的なツリー構造と複合パターンを調査する必要があります。複合パターンは通常、前に引用したウィジェットの例で使用されているものです。

于 2011-03-08T07:48:46.227 に答える