Avant la déclaration de la classe ne semble pas fonctionner en C++
Les suivantes code est compilé dans VC++6. Je ne comprends pas pourquoi j'obtiens l'erreur de compilation C2079: 'b' uses undefined class 'B'
pour le code suivant.
Classe B Source
#include "B.h"
void B::SomeFunction()
{
}
De Classe B De L'En-Tête
#include "A.h"
struct A;
class B
{
public:
A a;
void SomeFunction();
};
struct Un en-Tête
#include "B.h"
class B;
struct A
{
B b;
};
Si j'ai changé de catégorie B de l'en-tête pour la suite, alors il n'y aura pas d'erreur. Mais l'en-tête de la déclaration ne sera pas au top!
De classe B, en-Tête bizarre en-tête de la déclaration de
struct A;
class B
{
public:
A a;
void SomeFunction();
};
#include "A.h"
Pouvez-vous les mettre dans le même fichier d'en-tête? Je sais que ce n'est pas particulièrement réponse technique, mais vous pouvez éviter le tout ensemble en faisant cela, si c'est possible.
N'a pas d'importance si vous mettez les deux définitions de classes dans le même fichier d'en-tête, on a encore venir en premier et ne pouvait pas savoir la taille de l'autre classe.
merci pour la clarification, je suis encore très nouveau à cela, et espérait que je n'offrais pas de mauvais conseils, qui j'étais
N'a pas d'importance si vous mettez les deux définitions de classes dans le même fichier d'en-tête, on a encore venir en premier et ne pouvait pas savoir la taille de l'autre classe.
merci pour la clarification, je suis encore très nouveau à cela, et espérait que je n'offrais pas de mauvais conseils, qui j'étais
OriginalL'auteur Lopper | 2009-12-11
Vous devez vous connecter pour publier un commentaire.
Afin de définir une classe ou structure, le compilateur doit savoir de quelle taille de chaque variable membre de la classe. Une déclaration anticipée ne pas faire cela. Je ne l'ai jamais vu utilisé pour les pointeurs et (moins souvent) des références.
Au-delà de ça, ce que vous essayez de faire ici ne peut pas être fait. Vous ne pouvez pas avoir une classe A qui contient un objet d'une autre classe B qui contient une objet de la classe A. Vous peut, cependant, ont de la classe A contient un pointeur à la classe B qui contient une objet de la classe A.
B.cpp
B. h
A. h
Deux points. Tout d'abord, veillez à utiliser une certaine forme de idempotence de conserver les en-têtes d'être inclus plusieurs fois par unité de compilation. Deuxièmement, comprendre que, en C++, la seule différence entre les classes et les structures par défaut est le niveau de visibilité des classes de l'utilisation privée de la visibilité par défaut, tandis que les structures usage public de la visibilité par défaut. Les définitions suivantes sont fonctionnellement équivalent en C++.
J'ai toujours utilisé cette convention pour mon idempotence marques lorsque le compilateur ne génère pas automatiquement. Est-ce spécifique à un compilateur ou est-il dans le C++ spec?
c'est une partie du C++ spec que de tels identificateurs sont réservés. Personnellement, j'utilise "HEADER_PATH_TO_HEADER_H_INCLUDED" ou "HEADER_PATH_TO_HEADER_INCLUDED" (si aucun ".h").
OriginalL'auteur Matt Davis
Déclaration, comme
ou
Présenter comme Une de type incomplète et il reste incomplète jusqu'à la fin de ce type de définition est atteint. Il y a des choses que vous pouvez faire avec incomplètes et types de choses que vous ne pouvez pas. Vous pouvez
Vous ne pouvez pas
Dans votre code, vous essayez de déclarer struct membre de type incomplète. C'est illégal. Seuls les pointeurs et les références sont autorisés.
OriginalL'auteur Tadeusz Kopec
Vous essayez de créer l'objet avec l'avant de la déclaration. Compilateur en ce moment ( avec seulement de l'avant decl) ne peut pas décider de la taille de l'objet et, par conséquent, il ne peut pas allouer la mémoire nécessaire pour A. Si vous ne pouvez pas créer des objets avec seulement de l'avant decl.
Au lieu de les remplacer avec:
Pointeur ou une référence à Un sans Un de la définition de la classe fonctionnera très bien.
OriginalL'auteur aJ.
Deux questions de sauter hors de moi ici.
1: Vous avez écrit
Struct A
au lieu destruct A
; à noter que le bas-de-casse "s". Votre compilateur peut envisager l'équivalent, mais je ne pense pas que c'est la norme C++.Vous avez défini une référence circulaire entre
A
etB
. Chaque objet doit contenir unB
objet, mais chaqueB
objet doit contenir unA
objet! C'est une contradiction, et ne sera jamais la façon dont vous le souhaitez. L'habitude C++ façon de résoudre ce problème est d'utiliser des pointeurs ou des références pourA::b
ouB::a
(ou les deux).OriginalL'auteur David Seiler
Vous alse inclure A. h de B. h et B. h de A. h. Vous devez au moins utiliser les macros du préprocesseur:
de sorte que le fichier ne sera pas inclus plus d'une fois.
Double-traits de soulignement sont réservés pour le compilateur. L'utilisation d'une autre convention de nommage.
OriginalL'auteur el.pescado
Si vous créez une instance de A, qui permettra de créer une instance de B (membre var) qui va créer une instance d'Un membre du var) qui va créer une instance de B, ce qui va créer une instance de A et ainsi de suite...
Le compilateur ne doit pas permettre que cela car elle nécessite l'infini de la mémoire.
Pour résoudre ce problème, soit A ou B doit utiliser une référence/pointeur à l'autre classe.
OriginalL'auteur johnB