Domanda

Ho due classi e ciascuno di essi utilizza alcuni dei altra classe, su esempio:

// class1.h
class Class1;
#include "class2.h"

class Class1 {
  public:
  static Class2 *C2;
  ...
};

// class2.h
class Class2;
#include "class1.h"

class Class2 {
  public:
  static Class1 *C1;
  ...
};

E quando io definisco come nell'esempio sopra, funziona (ho anche un po 'per evitare #ifndef infinita intestazione recurency). Ma voglio anche aggiungere alcune funzioni inline per le mie classi. E ho letto qui che dovrei mettere definizione di funzione inline nel file di intestazione, perché non funziona se li metto in un file cpp e voglio chiamarli da un altro file cpp (quando lo faccio ho di riferimento non definito durante il collegamento). Ma il problema qui è con qualcosa di simile:

// class1.h
...
inline void Class1::Foo() {
  C2->Bar();
}

ottengo l'errore:. Uso non valido di tipo incompleto ‘struct Class2’

Quindi, come posso fare?

È stato utile?

Soluzione

È necessario ritardare inclusa l'intestazione, ma poi includerlo e definire i metodi in linea. In questo modo in ogni intestazione, sono autosufficienti e di cui uno sarà sempre includere l'altro, con includono guardie prevenire ricorsione infinita.

A.hpp

#ifndef INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD
#define INCLUDE_GUARD_B9392DB18D114C1B8DFFF9B6052DBDBD

struct B;

struct A {
  B* p;
  void foo();
};

#include "B.hpp"

inline
void A::foo() {
  if (p) p->bar();
}

#endif

B.hpp

#ifndef INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8
#define INCLUDE_GUARD_C81A5FEA876A4C6B953D1EB7A88A27C8

struct A;

struct B {
  A* p;
  void bar();
};

#include "A.hpp"

inline
void B::bar() {
  if (p) p->foo();
}

#endif

Altri suggerimenti

L'avete mix'd up. Quello che vuoi è:

// class1.h
class Class2;

class Class1 {
  public:
  static Class2 *C2;
  ...
};

// class2.h
class Class1;

class Class2 {
  public:
  static Class1 *C1;
  ...
};

e comprendono le rispettive intestazioni nella sorgente. La linea:

class Class1; // or Class2

dichiara un tipo incompleto , e si può avere puntatori e riferimenti a tipi incompleti. Al momento l'utilizzo, però, ha bisogno di essere completata. Quindi, basta dire "hey che sarà esiste!" nell'intestazione e nella fonte raccontare quello che è.

Il mio suggerimento è che si posiziona metodi comuni e membri in una classe di base, poi derivano C1 e C2 dalla classe base. Questo potrebbe risolvere il problema della dipendenza circolare.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top