C ++中的循环引用,没有指针

时间:2009-08-25 15:58:22

标签: c++ pointers circular-reference

有没有办法在不使用指针的情况下定义循环引用?

我需要这样的事情:

struct A;
struct B {
    A a;
};

struct A {
    B b;
};

谢谢!

5 个答案:

答案 0 :(得分:15)

不,没有。这样的结构将具有无限大小。

您可以使用智能指针(shared_ptrweak_ptr)来避免直接指针操作,但这就是它。

答案 1 :(得分:13)

您可以使用参考

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

struct A {
  B b;
};

但是如果没有一定程度的间接,就不可能创建一个循环引用。你的样本正在做什么甚至没有创建循环引用,它试图创建一个递归定义。结果将是无限大小的结构,因此不合法。

答案 2 :(得分: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) {}
};

答案 3 :(得分:1)

在C ++中,T o表示“T类型的对象,而不是对某些T的引用(例如,使用C#和Java中的引用类型)。来自您的问题的代码,类型A将具有类型为B的子对象(名为b),而B依次具有类型为{{A的子对象1}}(名为a)。现在,a内部会有另一个A(再次称为a),然后又有另一个B ,...

不,这不起作用。

你可能想要的是A 引用B,而A又会引用struct A; struct B { A* a; B(A*); }; struct A { B* b; A(B* b_) : b(b_) { if(b) b.a = this; } }; B::B(A* a_) : : a(a_) { if(a) a.b = this; } 。这可以使用指针来完成:

{{1}}

我认为不能使用引用来完成。

答案 4 :(得分: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;