Directement de Wikipedia :
En général, une unité de traduction ne doit pas contenir plus d'une définition de tout type de classe. Dans cet exemple, deux définitions de la classe type C se trouvent dans la même unité de même unité de traduction. Cela se produit généralement lorsqu'un fichier d'en-tête est inclus deux fois par le même fichier source sans que les protections d'en-tête appropriées.
class C {}; // first definition of C
class C {}; // error, second definition of C
n le suivant, formant un pointeur vers S ou définir une fonction prenant une référence à S sont des exemples de constructions légales, car elles ne exigent pas que le type de S soit complet. Par conséquent, une définition n'est pas nécessaire.
En définissant un objet de type S, une fonction prenant un argument de type S, ou l'utilisation de S dans une expression sizeof sont exemples de contextes où S doit être complet, et nécessitent donc une définition.
struct S; // declaration of S
S * p; // ok, no definition required
void f(S&); // ok, no definition required
void f(S); // ok, no definition required
S f(); // ok, no definition required
S s; // error, definition required
sizeof(S); // error, definition required
Plus d'une définition
Dans certains cas, il peut y avoir plus plus d'une définition d'un type ou d'un modèle. Un programme composé de plusieurs fichiers d'en-tête et fichiers source aura typiquement plus d'une définition d'un type, mais pas plus d'une pas plus d'une définition par unité unité.
Si un programme contient plus d'un définition d'un type, alors chaque définition doit être équivalente.
Définitions des membres des données statiques const
Dans le C++ pré-standard, toutes les données statiques statiques nécessitaient une définition en dehors de leur classe. Cependant, au cours du processus de normalisation du C++, il a été décidé de lever cette exigence pour les membres intégraux statiques constants. L'intention de intention était de permettre des utilisations telles que :
struct C
{
static const int N = 10;
};
char data[C::N]; // N "used" without out-of-class definition
sans définition de la portée de l'espace de nom pour N.
Néanmoins, le libellé de la norme C++ de 1998 exigeait toujours un définition si le membre est utilisé dans programme. Cela inclut le membre apparaissant partout sauf en tant que l'opérande de sizeof ou de typeid, rendant effectivement le programme ci-dessus mal formé.
Ceci a été identifié comme un défaut, et la formulation a été ajustée pour permettre un tel membre d'apparaître partout où une expression constante est requise, sans qu'il soit nécessaire d'utiliser une expression hors classe hors classe. Cela inclut les tableaux les limites de tableaux, les expressions de cas et les initialisateurs de membres non typés non typés.
struct C
{
static const int N = 10;
static const int U = N; // Legal per C++03
};
char data[C::N]; // Legal per C++03
template<int> struct D;
template<> struct D<C::N> {}; // Legal per C++03
Cependant, l'utilisation d'une intégrale statique const n'importe où, sauf là où un membre expression constante intégrale est nécessaire, il faut une définition
struct C
{
static const int N = 10;
};
int main()
{
int i = C::N; // ill-formed, definition of C::N required
}
Cette exigence sera assouplie dans la prochaine norme C++, appelée familièrement C++0x.