web-dev-qa-db-fra.com

Comment créer deux classes en C ++ qui s'utilisent comme données?

Je cherche à créer deux classes, chacune contenant un objet de l'autre type de classe. Comment puis-je faire ceci? Si je ne peux pas le faire, y a-t-il une solution de contournement, comme si chaque classe contient un pointeur vers l'autre type de classe? Merci!

Voici ce que j'ai:

Fichier: bar.h

#ifndef BAR_H
#define BAR_H
#include "foo.h"
class bar {
public:
  foo getFoo();
protected:
  foo f;
};
#endif

Fichier: foo.h

#ifndef FOO_H
#define FOO_H
#include "bar.h"
class foo {
public:
  bar getBar();
protected:
  bar b;
};
#endif

Fichier: main.cpp

#include "foo.h"
#include "bar.h"

int
main (int argc, char **argv)
{
  foo myFoo;
  bar myBar;
}

$ g ++ main.cpp

In file included from foo.h:3,
                 from main.cpp:1:
bar.h:6: error: ‘foo’ does not name a type
bar.h:8: error: ‘foo’ does not name a type
39
Steve Johnson

Vous ne pouvez pas avoir deux classes contenant directement des objets de l'autre type, car sinon vous auriez besoin d'un espace infini pour l'objet (puisque foo a une barre qui a un foo qui a une barre qui etc.)

Vous pouvez en effet le faire en faisant en sorte que les deux classes stockent des pointeurs l'une sur l'autre. Pour ce faire, vous devrez utiliser déclarations avancées afin que les deux classes connaissent l'existence de l'autre:

#ifndef BAR_H
#define BAR_H

class foo; // Say foo exists without defining it.

class bar {
public:
  foo* getFoo();
protected:
  foo* f;
};
#endif 

et

#ifndef FOO_H
#define FOO_H

class bar; // Say bar exists without defining it.

class foo {
public:
  bar* getBar();
protected:
  bar* f;
};
#endif 

Notez que les deux en-têtes ne s’incluent pas. Au lieu de cela, ils connaissent simplement l'existence de l'autre classe via les déclarations avancées. Ensuite, dans les fichiers .cpp de ces deux classes, vous pouvez #include l'autre en-tête pour obtenir les informations complètes sur la classe. Ces déclarations avancées vous permettent de rompre le cycle de référence de "foo needs bar needs foo needs bar."

93
templatetypedef

Cela n'a aucun sens. Si A contient B et B contient A, ce serait de taille infinie. Imaginez mettre deux boîtes et essayer de les mettre l'une dans l'autre. Ça ne marche pas, non?

Les pointeurs fonctionnent cependant:

#ifndef FOO_H
#define FOO_H

// Forward declaration so the compiler knows what bar is
class bar;

class foo {
public:
  bar *getBar();
protected:
  bar *b;
};
#endif
4
EboMike