Question

J'essaie de déclarer et d'utiliser une classe B à l'intérieur d'une classe A et définir B en dehors de A.
Je sais pertinemment que c'est possible parce que Bjarne Stroustrup
utilise cela dans son livre "Le langage de programmation C ++"

(page 293, par exemple, les classes String et Srep).

C’est donc mon code minimal qui pose problème

class A{
struct B; // forward declaration
B* c;
A() { c->i; }
};

struct A::B { 
/* 
 * we define struct B like this becuase it
 * was first declared in the namespace A
 */
int i;
};

int main() {
}

Ce code donne les erreurs de compilation suivantes dans g ++:

tst.cpp: In constructor ‘A::A()’:
tst.cpp:5: error: invalid use of undefined type ‘struct A::B’
tst.cpp:3: error: forward declaration of ‘struct A::B’

J'ai essayé de regarder la FAQ C ++ et le closeset que j'ai reçu était ici et ici mais
ceux qui ne s'appliquent pas à ma situation.
J'ai également lu ceci à partir d'ici, mais cela ne résout pas mon problème.

gcc et MSVC 2005 génèrent des erreurs de compilation à ce sujet

Était-ce utile?

La solution

Définissez le constructeur pour A APRES la définition de la structure B.

Autres conseils

L'expression c- > i déréférence le pointeur sur struct A :: B de sorte qu'une définition complète doit être visible à ce stade du programme.

La solution la plus simple consiste à rendre le constructeur de A non inline et à lui fournir un corps après la définition de struct A :: B .

C’est un bon exemple de la raison pour laquelle vous souhaitez séparer les définitions des déclarations. Vous devez changer l'ordre des choses pour que le constructeur A :: A () soit défini après la définition de struct A :: B .

class A
{
    struct B;
    B* c;
    A();
};

struct A::B
{
    int i;
};

A::A() { c->i; }

int main()
{
    return 0;
}

Fait intéressant, j'ai rencontré le même problème avec la page 293 ("11.11 Une classe de chaînes") mentionnée dans le livre Stroustrup.

L'exemple fourni dans le livre imprimé semble être fautif, fournissant les méthodes suivantes en ligne, au lieu de les définir après la définition de struct Srep

class String {
  // ...
  void check(int i) const { if (i<0 || rep->sz <=i) throw Range(); }
  char read(int i) const { return rep->s[i]; }
  void write(int i, char c) { rep=rep->get_own_copy(); rep->s[i]=c; }
  ...etc...

J'ai un peu cherché sur Google et trouvé la dernière implémentation de l'auteur de cette classe de chaînes, disponible ici:    http://www2.research.att.com/~bs/string_example.c

Il semble l'avoir modifié pour que ces méthodes ne soient plus en ligne, afin d'éviter le problème mentionné dans ce fil.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top