ポインターを使用せずに循環参照を定義する方法はありますか?
私はこのようなものを持っている必要があります:
struct A;
struct B {
A a;
};
struct A {
B b;
};
ありがとう!
ポインターを使用せずに循環参照を定義する方法はありますか?
私はこのようなものを持っている必要があります:
struct A;
struct B {
A a;
};
struct A {
B b;
};
ありがとう!
代わりに参照を使用できます
struct A;
struct B {
A& a;
};
struct A {
B b;
};
しかし、ある程度の間接性なしに循環参照を作成することはできません。サンプルが行っていることは、循環参照を作成することでもなく、再帰的な定義を作成しようとしています。その結果、無限のサイズの構造体になるため、正当ではありません。
いいえ、ありません。そのような構造は無限のサイズを持つでしょう。
スマート ポインター ( shared_ptrおよびweak_ptr ) を使用して、ポインターの直接操作を回避できますが、それだけです。
これはどのように機能しますか?私の記憶が正しければ、参照のアドレス値は一度設定すると変更できないため、循環参照を定義することはできません。
次のように機能します (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) {}
};
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;