C'è un modo per definire riferimenti circolari senza utilizzare i puntatori?Riferimento circolare in C++ senza puntatori
ho bisogno di avere somthing come questo:
struct A;
struct B {
A a;
};
struct A {
B b;
};
Grazie!
C'è un modo per definire riferimenti circolari senza utilizzare i puntatori?Riferimento circolare in C++ senza puntatori
ho bisogno di avere somthing come questo:
struct A;
struct B {
A a;
};
struct A {
B b;
};
Grazie!
È possibile utilizzare i riferimenti al posto
struct A;
struct B {
A& a;
};
struct A {
B b;
};
Ma no non è possibile creare un riferimento circolare senza un certo livello di indirezione. Ciò che sta facendo il tuo campione non è nemmeno la creazione di un riferimento circolare, ma sta tentando di creare una definizione ricorsiva. Il risultato sarebbe una struttura di dimensioni infinite e quindi non legale.
Come potrebbe funzionare? Se ricordo bene, il valore dell'indirizzo di un riferimento non può essere modificato una volta impostato, quindi non è possibile definire un riferimento circolare. –
@ John, sinceramente non ne sono sicuro. L'OP ha però chiesto se fosse possibile definirne uno. Questa definizione è legale e compila (VS2008 SP1). – JaredPar
Il costruttore per B prenderebbe un riferimento ad un A e il costruttore per A inizializzerebbe il suo membro B con * this. –
No, non c'è. Tale struttura avrebbe dimensioni infinite.
È possibile utilizzare i puntatori intelligenti (shared_ptr e weak_ptr) per evitare la manipolazione diretta del puntatore, ma questo è tutto.
Come potrebbe funzionare? Se ricordo bene, il valore dell'indirizzo di un riferimento non può essere modificato una volta impostato, quindi non è possibile definire un riferimento circolare.
Potrebbe funzionare nel modo seguente (identica all'Esempio di Jared inclusa costruttori definito):
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) {}
};
Vecchio thread, ma ho appena usato la soluzione in una macchina a stati, vedere il commento qui sotto. – kert
In C++, T o
significa "un oggetto di tipo T
, non un riferimento a qualche T
(come, per esempio, con i tipi di riferimento in C# e Java). con il codice dalla tua domanda, tipo A
avrebbe un oggetto sub di tipo B
(chiamato b
), e che B
a sua volta, avrebbe un oggetto sub di tipo A
(nome a
). Ora, quello a
avrebbe a sua volta un altro A
all'interno (di nuovo chiamato a
), che poi ha un altro B
, che ...
No, questo non funzionerà.
Che probabilmente si desidera è che un A
siano state ottenute ad un B
, che a loro volta siano state ottenute che A
. Questo può essere fatto usando i puntatori:
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; }
Non penso che si possa fare usando i riferimenti.
soluzione ChrisW può essere generalizzato un po 'come questo:
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) {}
};
Questo ora permette di fare
Context<State1> demo;
Inoltre, Stato può avere un po' di codice di supporto template così
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) {}
};
Che ora ti permette di fare qualsiasi di
Context<State2> demo2;
Context<State3> demo3;
Nota: Sembra logico per me inoltrare-dichiarare che 'A' è un' class' e successivamente definirlo come 'struct'. – sbi
Quanto sopra non può essere compilato (e non sotto vs2008) perché A non è definito quando viene definita la struttura B. (btw, sì le vostre dichiarazioni future: struct/class dovrebbe corrispondere alle definizioni) – quamrana