10
votes

Pourquoi êtes-vous _have_ pour initialiser une variable de membre statique C ++?

Je sais que vous initialisez généralement une variable de membre statique à partir d'un fichier .CPP. Mais ma question est la suivante: pourquoi êtes-vous avez à?

Voici un exemple: xxx

ceci donne une erreur de compilateur: référence non défini à 'A :: x'

Cependant, ceci: xxx

compile et fonctionne bien.

Je peux comprendre si j'imitié si j'imitié le vecteur en utilisant autre chose que le constructeur par défaut, mais je ne suis pas. Je veux juste un vecteur de taille 0 créé. Certains membres statiques devront être attribués de mémoire sur l'initialisation du programme, alors pourquoi le compilateur n'utilise-t-il que le constructeur par défaut?


0 commentaires

4 Réponses :


2
votes

Qu'est-ce que vous appelez l'initialisation est la définition. Vous devez définir le membre statique quelque part. La partie à l'intérieur de la classe n'est qu'une déclaration.

Ceci est principalement parce que la définition de l'en-tête causerait d'énormes problèmes (puisque vous ne pouviez pas inclure cet en-tête dans une seule unité de traduction sans provoquer plusieurs définitions).


0 commentaires

9
votes

Vous le regardez à partir du point d'une seule unité de compilation.

Mais la langue doit supposer qu'il peut potentiellement par plusieurs unités de compilation. Alors maintenant, dans quelle unité de compilation est l'objet statique créé? Fondamentalement, le compilateur n'est pas autorisé à faire cette décision et l'ingénieur doit prendre la décision.


0 commentaires

4
votes

référence non défini à 'A :: x' n'est pas une erreur de compilateur; C'est une erreur de liaison. Cela signifie qu'une définition de a :: x ne peut être trouvée dans aucune des unités de traduction qui sont liées ensemble pour former votre programme. Les variables d'éléments statiques ont une liaison externe et doivent être définies dans une seule unité de traduction. Tout ce qui avec une liaison externe n'aura pas de définition générée par le compilateur à moins que vous n'écrivez à une.


0 commentaires

17
votes

C'est pas sur l'initialisation , il s'agit de définition . Ou plus précisément: Il s'agit de savoir quelle unité de compilation (.cpp) tiendra l'objet (qui doit être défini de manière unique quelque part)

Donc, ce qui est nécessaire, c'est simplement mettre la définition quelque part , dans un lieu unique , c'est un CPP, de laisser le compilateur savoir que lorsque l'objet statique de la classe est appelé, il est défini là-bas et nulle part ailleurs. (Si vous essayez de définir votre statique dans un en-tête, chaque RPC, y compris cet en-tête aura une définition, il est impossible de savoir où il devrait être défini - et initialisé manuellement s'il est nécessaire pour votre utilisation) .


5 commentaires

+1 Mais vous devez supprimer l'un des DUPS. Pour les objets, Raii rend l'initialisation (même si seulement par constructeur par défaut) une conséquence de la définition. Est-ce que cela fonctionne pour les pointeurs bruts, des types intégrés tels que int ?


Je voulais dire que vous pouvez ajouter l'initialisation là-bas si vous le souhaitez. Je vais ajouter la précision.


@Steve POD Type Constructeurs sont syntaxiques uniquement, alors oui, il fonctionne, mais cela ne fait rien (ou d'être encore plus précis, il est autorisé à ne rien faire - par la norme C ++).


Merci, cela a beaucoup de sens maintenant. Je suppose que je me suis rattrapé avec pensée que la déclaration dans le fichier d'en-tête était suffisante pour réserver la mémoire. Mais bien sûr, il ne peut pas être, car un fichier d'en-tête est inclus dans de nombreux fichiers d'objets. Il est logique que vous devez explicitement indiquer quel fichier d'objet allouera la mémoire en donnant la définition statique définition dans un fichier .cpp.


Il pourrait toujours être étrange lors de ses provenants d'autres langues, car la raison est relative à un ancien système d'unité de compilation de fichiers. Pas sûr qu'il sera conservé au cours de la prochaine décennie. Il semble y avoir beaucoup d'intérêt dans un système basé sur le module pour C ++ 15-16 ou plus tard.