5

ポインターを使用せずに循環参照を定義する方法はありますか?

私はこのようなものを持っている必要があります:

struct A;
struct B {
    A a;
};

struct A {
    B b;
};

ありがとう!

4

5 に答える 5

15

代わりに参照を使用できます

struct A;
struct B {
  A& a;
};

struct A {
  B b;
};

しかし、ある程度の間接性なしに循環参照を作成することはできません。サンプルが行っていることは、循環参照を作成することでもなく、再帰的な定義を作成しようとしています。その結果、無限のサイズの構造体になるため、正当ではありません。

于 2009-08-25T16:03:39.253 に答える
15

いいえ、ありません。そのような構造は無限のサイズを持つでしょう。

スマート ポインター ( shared_ptrおよびweak_ptr ) を使用して、ポインターの直接操作を回避できますが、それだけです。

于 2009-08-25T16:04:12.247 に答える
7

これはどのように機能しますか?私の記憶が正しければ、参照のアドレス値は一度設定すると変更できないため、循環参照を定義することはできません。

次のように機能します (Jared の例と定義されたコンストラクターと同じです)。

struct A;

struct B {
  A& m_a;
  B(A& a) : m_a(a) {}
};

struct A {
  B m_b;
  //construct B m_b member using a reference to self
  A() : m_b(*this) {}
  //construct B m_b member using a reference to other
  A(A& other) : m_b(other) {}
};
于 2009-08-25T16:16:00.680 に答える
0

ChrisW のソリューションは、次のように少し一般化できます。

template <class defaultState> struct Context;

struct State1 {
    Context<State1>& mContext;
    State1(Context<State1> & ref) : mContext(ref) {}
};

template <class TDefaultState>
struct Context {
    TDefaultState mState;
    Context() : mState(*this) {}
};

これにより、次のことが可能になります

Context<State1> demo;

さらに、State にはいくつかのテンプレート ヘルパー コードも含めることができます。

template <class State>
struct TState {
    typedef Context<State> TContext;
    typedef TState<State> TBase;
    Context<State> & mContext;
    TState(Context<State> &ref) : mContext(ref) {}
};

struct State2 : TState<State2> {
    State2(TContext & ref) : TBase(ref) {}
};
struct State3 : TState<State3> {
    State3(TContext & ref) : TBase(ref) {}
};

これにより、次のいずれかを実行できるようになりました

Context<State2> demo2;
Context<State3> demo3;
于 2014-08-04T21:16:44.903 に答える