Dans le code suivant:

class B;

struct A
{
   B* b; // <- why MUST be a pointer? Why size cannot be calculated later...?
}

struct B
{
   ...
}

Autant que je sache, struct A doit définir b comme B *, car le compilateur ne peut pas dire la taille de B lors du calcul de la taille de A.

Ce que je ne comprends pas, c'est pourquoi le compilateur ne peut pas reporter le calcul jusqu'à ce qu'il trouve la définition complète de B (comme cela a été promis par le programmeur en transmettant déclarer la classe)

3
TCS 3 nov. 2020 à 12:09

3 réponses

Meilleure réponse

Imaginez que vous pourriez définir A comme:

class B;

struct A {
   B b; // not a pointer
}

Autrement dit, b est une donnée membre de type incomplet - le compilateur ne connaît pas la taille de B à ce stade.

Ensuite, si B était défini comme:

struct B {
   A a;
}

Cela nécessiterait une mémoire infinie.

5
ローウ 3 nov. 2020 à 09:18

Essentiellement, un pointeur est une adresse en mémoire. Pour avoir une telle adresse, vous n'avez pas besoin de connaître la taille de l'objet vers lequel elle pointe.

Mais vous ne pouvez pas faire grand-chose avec un pointeur vers un type incomplet. Par exemple:

  • vous ne pouvez pas créer un nouvel objet avec une nouvelle expression (quel est le constructeur?)

  • vous ne pouvez pas utiliser l'arithmétique du pointeur (quelle est la taille de l'objet?)

  • etc, ... voir ici.

La possibilité d'avoir un pointeur vers un type incomplet est en fait plutôt utile, par exemple cela permet le Idiome PImpl.

0
francesco 3 nov. 2020 à 09:34

La raison en est simplement que C ++ est conçu pour être compilé en un seul passage dans le code source (plus ou moins); le but est que le compilateur n'ait pas à reporter la compilation de quelque chose car il n'y a pas assez d'informations au point où elles sont définies.

0
Pete Becker 3 nov. 2020 à 14:14