有没有办法在不使用指针的情况下定义循环引用?
我需要这样的事情:
struct A;
struct B {
A a;
};
struct A {
B b;
};
谢谢!
答案 0 :(得分:15)
不,没有。这样的结构将具有无限大小。
您可以使用智能指针(shared_ptr和weak_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;