2010-12-01 3 views
9

Mon compilateur C++ se plaint lorsque j'essaie d'initialiser une variable membre int dans la définition de classe. Il dit que "seuls les membres de données intégraux statiques peuvent être initialisés dans une classe". Pouvez-vous s'il vous plaît expliquer la raison derrière cette restriction (si possible avec exemple).Pourquoi l'initialisation de la variable membre entier (qui n'est pas statique) n'est pas autorisée en C++?

+0

À moins que l'entier dont vous parlez ne soit commun pour tous les objets du type que vous définissez, quelle utilisation avez-vous dans une variable membre à laquelle une valeur est affectée? Appeler cette variable statique const est le moyen de dire au compilateur que la variable est commune à tous les objets du type. – vpit3833

+0

J'essaie d'éviter l'initialisation dans le constructeur, en donnant une valeur par défaut à la variable membre. – Sulla

+1

Voir http://stackoverflow.com/questions/370283/why-cant-i-have-a-non-integral-static-const-member-in-a-class et http://stackoverflow.com/questions/ 3575580/rationale-behind-static-const-member-initialization-syntax pour de bonnes informations. – sje397

Répondre

8

La logique est la nature «de bas niveau» de C++. Si cela le permettait, le compilateur aurait besoin de générer un code d'initialisation pour tous les constructeurs, ce qui n'est pas entièrement clair pour le développeur. Après tout, il peut être nécessaire d'initialiser les membres des classes de base sur la construction d'une classe dérivée même lorsque les constructeurs de classe de base ne sont pas explicitement appelés.

Les variables d'intégrale statiques constantes n'ont pas besoin d'être initialisées lors de la création de l'objet.

+0

Parce qu'il reste le même, le compilateur peut simplement remplacer les constantes par leurs valeurs. – Tomas

+0

Voir ma réponse - statique implique que ce n'est pas une instance par instance, et en tant que tel n'est pas lié au constructeur. – EboMike

+0

Les intégrales de constantes statiques ne sont initialisées qu'une seule fois et pas à chaque fois qu'un objet de cette classe est construit. –

3

Je vous devine vous essayez de le faire:

class foo { 
    int m_iX = 5; 
}; 

Il faudrait code à exécuter dans le constructeur, car chaque instance nouvellement créée aurait besoin d'initialiser cette variable. En C++, tout le code qui est exécuté pendant le constructeur est (heureusement) contenu dans le constructeur lui-même, donc il est immédiatement évident ce que la construction de la classe implique. De plus, comme une classe peut avoir un nombre quelconque de constructeurs (y compris les constructeurs de copie), il serait ambigu comme lorsque cette initialisation devrait ou ne devrait pas avoir lieu.

Vous pouvez le faire:

class foo { 
    enum { 
     CONSTANT = 8 
    }; 
}; 

Cela vous permet d'utiliser foo::CONSTANT. Cela fonctionne puisque ce sera par classe plutôt que par instance.

De même, vous pouvez le faire:

class foo { 
    static int sm_iX; 
}; 

dans le Cpp:

int foo::sm_ix = 5; 

Encore une fois, cela est par classe, et non par instance, et en tant que telle ne concerne pas la construction d'une instance réelle.

Bonus - si vous déclarez cet int const, de nombreux compilateurs peuvent l'évaluer lors de la compilation.

0

Arun,

Je crois que votre question est liée à
Compiler Error C2864

Pour obtenir ce que vous voulez faire, C++ vous oblige à initialiser exemple des membres spécifiques (ex: non statique, non coût) soit dans le constructeur corps ou la liste d'initialisation.

4

La restriction statique existe parce que C++ utilise initializers constructeur pour initialiser les membres de données non statiques:

struct Example { 
    int n; 
    Example() : n(42) {} 
}; 

La restriction const existe parce que le cas const est traitée spécialement (plutôt que dans l'autre sens) de sorte que statique Les membres intégraux const peuvent généralement être traités comme s'ils avaient un lien interne, similaire aux variables const au niveau de l'espace de noms (C++ 03 §7.1.5.1p2, si cela vous intéresse). Cela est principalement utile pour utiliser les membres dans des expressions constantes intégrales, telles que les tailles de tableau.

11

Parce que cela n'est pas autorisé dans la norme actuelle. According to Bjarne, vous serez en mesure de le faire en C++ 0x. Si vous en avez vraiment besoin, essayez de mettre le compilateur en C++ 0x (-std=c++0x dans GCC) et voyez si votre compilateur le supporte.

Questions connexes