4 votes

Quelqu'un peut-il expliquer ce paragraphe de l'actuel projet de norme C++0x ?

Quelqu'un peut-il expliquer cette déclaration de la norme ISO N3242 §3.2, 4ème point

La partie ajoutée de la norme n3242 par rapport à la norme ISO 2003 :

4 Une seule définition d'une classe est requise dans une unité de traduction si la classe est utilisée d'une manière qui exige que le type de classe soit complet.

Un type de classe T doit être complet si :

  • un membre de données de classe non statique de type T est déclaré (9.2), ou
  • T est utilisé comme type d'objet ou d'élément de tableau dans une nouvelle expression
  • le type T est le sujet d'une expression alignof (5.3.6), ou bien
  • une déclaration d'exception a le type T , référence à T ou un pointeur vers T

Quelqu'un peut-il expliquer ce paragraphe de l'actuel projet de norme C++0x ?

Quelle est la signification réelle de l'ajout de cette phrase dans ces déclarations ?

Quelqu'un peut-il expliquer cela à l'aide d'un exemple/programme ?

6voto

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.

0voto

Mark B Points 60200

Tout ce que cela dit, c'est que si vous utilisez un type de classe (et ils listent explicitement les façons d'utiliser une classe) d'une manière qui nécessite une définition, vous devez fournir exactement une définition de cette classe.

Si vous ne fournissez pas de définition, c'est une erreur. Si vous en fournissez plus d'une dans une unité de traduction, c'est une erreur. Si vous fournissez plus d'une définition dans plusieurs unités de traduction, c'est un comportement non défini.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X