web-dev-qa-db-fra.com

c ++ Erreur "Type incomplet non autorisé" lors de l'accès aux informations de référence de classe (Dépendance circulaire avec déclaration directe)

Quelques problèmes dans mon code concernant récemment ce que je sais maintenant en tant que dépendance circulaire. En bref, il existe deux classes, Player et Ball, qui doivent toutes deux utiliser les informations de l'autre. À un moment donné du code, une référence à l'autre sera transmise (à partir d'une autre classe qui inclura les deux fichiers .h).

Après l'avoir lu, j'ai supprimé les fichiers # include.h de chacun d'entre eux et j'ai procédé à la déclaration en aval. Cela a résolu le problème de pouvoir déclarer les classes les unes dans les autres, mais il me reste maintenant une "erreur de type incomplet" lorsque je tente d'accéder à une référence passée à l'objet. Il semble y avoir quelques exemples similaires, bien que souvent mélangés à un code plus complexe et difficile à cerner.

J'ai réécrit le code dans sa forme la plus simple (un squelette essentiellement).

Ball.h:

class Player;

class Ball {
public:
    Player& PlayerB;
    float ballPosX = 800;
private:

};

Player.h:

class Ball;

class Player {
public:
    void doSomething(Ball& ball);
private:
};

Player.cpp:

#include "Player.h"

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}

Toute aide pour comprendre pourquoi c'est le cas serait grandement appréciée :)

29
nat1707828

Si vous placez vos définitions dans cet ordre, le code sera compilé

class Ball;

class Player {
public:
    void doSomething(Ball& ball);
private:
};

class Ball {
public:
    Player& PlayerB;
    float ballPosX = 800;
private:

};

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}

int main()
{
}

La définition de la fonction doQuelque chose nécessite la définition complète de la classe Ball car elle accède à son membre de données.

Dans votre exemple de code, Player.cpp n'a pas accès à la définition de la classe Ball, le compilateur génère donc une erreur.

20
Vlad from Moscow

Player.cpp nécessite la définition de Ball classe. Ajoutez donc simplement #include "Ball.h"

Player.cpp:

#include "Player.h"
#include "Ball.h"

void Player::doSomething(Ball& ball) {
    ball.ballPosX += 10;                   // incomplete type error occurs here.
}
15
Nima Soroush

Voici ce que j'avais et ce qui a causé mon "erreur de type incomplet":

#include "X.h" // another already declared class
class Big {...} // full declaration of class A

class Small : Big {
    Small() {}
    Small(X); // line 6
}
//.... all other stuff

Ce que j'ai fait dans le fichier "Big.cpp", où j'ai déclaré le constructeur de l'A2 avec X comme paramètre, est ..

Big.cpp

Small::Big(X my_x) { // line 9 <--- LOOK at this !
}

J'ai écrit "Small :: Big" au lieu de "Small :: Small", quelle erreur stupide .. J'ai reçu l'erreur "le type incomplet est maintenant autorisé" pour la classe X tout le temps (en lignes 6 et 9), ce qui a créé une confusion totale.

Quoi qu’il en soit, c’est là qu’une erreur peut se produire, et la principale raison est que j’étais fatigué quand je l’écrivais et j’avais besoin de 2 heures d’exploration et de réécriture du code pour le révéler.

2
Casper