Question

Cette référence post à la règle d'une définition.

Wikipedia est assez mal à expliquer comment la mettre en œuvre

Où puis-je trouver de bonnes ressources sur les lignes directrices à suivre en C ++ .NET?

Était-ce utile?

La solution

La règle d'une définition signifie essentiellement que ne peut se trouver une variable / fonction à un endroit dans l'espace d'adressage de l'exécutable compilé. Une façon de penser est pendant que vous compilez, il y a un tableau de mémoire à utiliser dans le programme compilé (code objet), et une table de consultation pour faire référence à des emplacements variables / fonction. Cela se fait sur un niveau par processus. Supposons que ce qui suit est un programme simple:

file1.cpp

int square(int x); // this is a declaration
extern int someVariable; // this is a declration

void square(int x)  // this is a definition
{
    return x * someVariable;
}

file2.cpp

int square(int x); // this is a declaration

int someVariable; // this is a definition    
void main()
{
    someVariable = 12;
    someVariable = square(4);
}       

Lorsque le compilateur commence la compilation du code objet, il se lit dans les déclarations, et met chose dans sa table. À la fin de la compilation file1.cpp, il finira avec quelque chose comme ceci:

declarations:
    square (XX): function that returns int, and takes a single int as parameter [4 bytes]
    someVariable (YY): integer [4 bytes]
data:
    12 34 56 78 aa XX XX XX XX ab cd
definition:
    square: starts at address 0

Cela suppose que la fonction est compilée à ces instructions de montage particulières. Au moment de l'éditeur de liens, XX XX XX XX se remplacée par l'adresse de somevariable.

Fichier2 finit par quelque chose comme:

declarations:
    square (XX): function that returns int, and takes a single int as parameter [4 bytes]
    someVariable (YY): integer [4 bytes]
data:
    00 00 00 00 12 34 56 78 12 34 56 YY YY YY YY 23 21
definitions:
    someVariable: starts at address 0
    main: starts at address 4

Et dans ce cas, l'AA sera remplacée par l'adresse de la place.

C'est là l'éditeur de liens entre en jeu. Le travail de l'éditeur de liens est de passer par la liste, et de construire une table où tout est dans l'espace d'adressage du programme au moment de la compilation. Cependant, il y a un problème si deux fichiers d'objet ont la même définition d'une variable quand il essaie de lier. S'il y avait deux définitions de somevariable dans l'exemple ci-dessus, il ne sait quoi remplacer AA avec. De même, s'il y a pas de définition , vous obtenez des erreurs de l'éditeur de liens laids.

La « solution » à la règle est de partitionner votre fichier tel que vous avez des définitions uniquement dans les fichiers .cpp, et ont des déclarations de choses dans vos fichiers .h, de sorte que l'exemple ci-dessus deviendrait:

file1.cpp

#include "file2.h"

void square(int x)  // this is a definition
{
    return x * someVariable;
}

file1.h

int square(int x); // this is a declaration

file2.cpp

#include "file1.h"

int someVariable; // this is a definition    
void main()
{
    someVariable = 12;
    someVariable = square(4);
}

file2.h

extern int someVariable;

Notez que ceci est un exemple très simple, et qu'il ne s'applique pas vraiment dans .NET car il n'y a pas un concept d'une distinction entre une déclaration et la définition.

Autres conseils

La meilleure façon de se conformer à la règle d'une définition est de mettre la définition dans un fichier .cpp au lieu de l'en-tête.

Les gens mettent parfois des définitions en-têtes à l'aide de macros et / ou pour faire préprocesseur conditionals l'objet ou la fonction définie dans une seule unité de compilation. Mais il est plus facile généralement (et certainement plus compréhensible) de mettre juste la définition dans un fichier .cpp.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top