Les Données Statiques De L'Initialisation De Membre
Pourquoi doit-statique des données d'initialisation de membre à l'extérieur de la classe?
class X
{
public:
int normalValue = 5; //NSDMI
static int i;
};
int X::i = 0;
Pourquoi la donnée membre statique (ici "je"), seule une déclaration, pas une définition?
Parce que. 😉 C'est juste la façon dont le langage est défini. 😉
Vous êtes autorisé
ce n'est pas encore une définition, et parfois une définition est nécessaire, voir gcc.gnu.org/wiki/...
Vous êtes autorisé
static const int i = 10
.ce n'est pas encore une définition, et parfois une définition est nécessaire, voir gcc.gnu.org/wiki/...
OriginalL'auteur CyberGuy | 2012-07-02
Vous devez vous connecter pour publier un commentaire.
Il est important de distinguer la initialiseur qui dit ce que sa valeur initiale est, et la définition. Cette modification du code est valide, avec l'initialiseur, dans la définition de classe:
c'est à dire Ce qui doit être à l'extérieur de la classe est une définition, pas l'initialisation.
C'est parce qu'une variable doit avoir une adresse en mémoire (à moins qu'il n'est utilisé que dans des situations limitées, comme dans le temps de compilation des expressions constantes.)
Un non-membre statique de la variable existe à l'intérieur de l'objet, il est un membre de, de sorte que son adresse en fonction de l'adresse de l'objet qui le contient. Chaque fois que vous créez un nouveau
X
vous pouvez également créer un nouveauX::normalValue
variable. La non-membre de données statiques de la vie commence avec le constructeur de la classe. NSDMI syntaxe n'a rien à voir avec la variable de l'adresse en mémoire, il permet simplement de donner une valeur initiale dans un seul endroit, plutôt que de le répéter à chaque constructeur un constructeur explicite liste d'initialiseur.D'autre part, une variable membre statique n'est pas contenue dans une instance de la classe, il existe indépendamment de toute instance unique et existe depuis le début du programme, à une adresse fixe. Pour qu'une variable membre statique (ou tout autre objet global) pour obtenir une adresse unique à l'éditeur de liens doit voir exactement une définition de la variable statique, dans un fichier objet, et de lui attribuer une adresse.
Car une variable statique besoins exactement une définition dans un fichier objet, il ne fait pas de sens pour permettre à cette définition, pour être fourni dans la classe, puisque les définitions de classe existent généralement dans les fichiers d'en-tête et sont inclus dans plusieurs fichiers objets. Ainsi, bien que vous pouvez fournir un initialiseur de la classe, vous devez toujours définir la donnée membre statique quelque part.
Vous pouvez aussi le regarder comme le fait de déclarer un
extern
variable:Ce déclare la variable, mais il doit y avoir une définition quelque part dans le programme:
i
pas êtreconst
ouconstexpr
pour que cela fonctionne, si c'est une donnée membre statique?Doute - à Chaque fois que vous créez un nouveau X vous pouvez également créer un nouveau
X::i
variable. Ne devrait pas être comme cela "Chaque fois que vous créez un nouveau X vous pouvez également créer un nouveauX::normalValue
variable".vous ne savez pas si j'ai été suggérant que "si
i
était non-statique alors ..." ou si j'étais tout simplement stupide, je l'ai changé pournormalValue
que c'est plus clair, merci."Every time you create a new X you also create a new X::normalValue variable."
Qui est faux selon votre propre répondreOriginalL'auteur Jonathan Wakely
Vous devez fournir une définition distincte pour une donnée membre statique (si sa odr-utilisé, tel que défini en C++11) tout simplement parce que cette définition doit résider quelque part - dans une et une seule unité de traduction. Données de classe statique membres sont essentiellement des objets globaux (variables globales) a déclaré en contexte de classe. Le compilateur veut que vous choisissez une unité de traduction spécifique qui va contenir le "corps" de chaque objet global. C'est vous qui décider qui est l'unité de traduction à la place de l'objet réel.
J'ai enlevé le mauvais "en C++11 tous les membres statiques peuvent avoir des initialiseurs de trop" réclamation de ma réponse.
OriginalL'auteur AnT
"statique" membre de la classe est comme un affectés globalement variable (elle n'est pas liée à la seule instance de classe), donc il doit résider dans certains fichier de l'objet (et être déclaré dans l' ".rpc" fichier), comme un symbole, tout comme toute variable globale.
Simple membre de la classe (non statique) réside dans le bloc de mémoire alloué pour l'instance de classe.
OriginalL'auteur Viktor Latypov
La simple raison est parce que les classes sont généralement déclarés dans en-tête fichiers, qui sont souvent inclus dans plusieurs fichiers cpp. Les données membres statiques ont une liaison externe et doit être déclarée dans exactement une unité de traduction qui les rend impropres à être définie à l'intérieur d'une classe.
Comme juanchopanza points de la manière suivante:
Cependant, ce n'est qu'une déclaration pas une définition. Vous devez toujours définir si vous allez utiliser
i
s'adresse quelque part.Par exemple:
OriginalL'auteur Jesse Good
Garder à l'esprit qu'il est possible d'initialiser les données statiques membre au moment de la déclaration, si elle est de const type intégral de const type d'énumération:
Du C++03 standard, §9.4.2
OriginalL'auteur juanchopanza
Lorsque le compilateur de générer le code binaire à partir d'une unité (simplification extrême: un fichier cpp et tous ses en-têtes), il émet un symbole pour la variable statique et, finalement, le code d'initialisation de cette variable.
Il est bon pour une variable statique symbole à être déclarées en unités multiples, mais il n'est pas correct d'être initialisé à plusieurs reprises.
Vous devez donc vous assurer que le code d'initialisation n'est émise pour une seule unité.
Cela signifie que la statique de la variable doit être définie dans un seul appareil.
Au lieu de penser à l'initialisation, je trouve que c'est plus utile de penser en termes d'adresses. La statique de la variable doit avoir une adresse, et seulement de l'adresse, de sorte qu'il doit être défini dans exactement une unité de traduction, de sorte que le linker peut-il donner une adresse.
OriginalL'auteur Gigi
Donnée Membre Statique
OriginalL'auteur Heemanshu Bhalla