Mettez-vous dans le compilateur de position: lorsque vous transférez déclarer un type, tout le compilateur sait, c'est que ce type existe; il ne sait rien au sujet de sa taille, les membres ou les méthodes. C'est pourquoi il est appelé un type incomplète. Par conséquent, vous ne pouvez pas utiliser le type de déclarer un membre, ou d'une classe de base, puisque le compilateur aurait besoin de savoir la mise en page de ce type.
En supposant que le terme suivantes déclaration.
class X;
Voici ce que vous pouvez faire et ne pas faire.
Ce que vous pouvez faire avec un type incomplète:
-
Déclarer un membre d'un pointeur ou d'une référence à la nature incomplète de type:
class Foo {
X *pt;
X &pt;
};
-
Déclarer des méthodes ou des fonctions qui acceptent/retour incomplet types:
void f1(X);
X f2();
-
Définir des méthodes ou des fonctions qui acceptent de rendement/pointeurs/références pour le type incomplète (mais sans l'aide de ses membres):
void f3(X*, X&) {}
X& f4() {}
X* f5() {}
Ce que vous ne pouvez pas faire avec un type incomplète:
-
L'utiliser comme une classe de base
class Foo : X {} // compiler error!
-
L'utiliser pour déclarer un membre:
class Foo {
X m; // compiler error!
};
-
Définir des méthodes ou des fonctions à l'aide de ce type
void f1(X x) {} // compiler error!
X f2() {} // compiler error!
-
Utiliser ses méthodes ou des champs, en fait en essayant de déréférencer une variable de type incomplète
class Foo {
X *m;
void method()
{
m->someMethod(); // compiler error!
int i = m->someField; // compiler error!
}
};
Quand il s'agit de modèles, il n'y a pas de règle absolue: si vous pouvez utiliser un type incomplète comme un paramètre du modèle dépend de la façon dont le type est utilisé dans le modèle.
Par exemple, std::vector<T>
nécessite son paramètre pour être complet, tandis que le boost::container::vector<T>
ne le sont pas. Parfois, un type est nécessaire que si vous utilisez certaines fonctions de membre; c'est le cas pour std::unique_ptr<T>
, par exemple.
Bien documentée modèle doit indiquer dans sa documentation à toutes les exigences de ses paramètres, y compris la nécessité de compléter les types ou pas.