Pourquoi l'avant-est nécessaire de déclarer C++
Le compilateur veut vérifier que vous avez pas fait des fautes d'orthographe ou dépassé le nombre incorrect d'arguments à la fonction. Ainsi, il insiste sur le fait qu'il voit d'abord une déclaration de 'add' (ou d'autres types, classes ou fonctions) avant qu'il ne soit utilisé.
Cela permet vraiment au compilateur de mieux valider le code et de le ranger pour qu'il puisse produire un fichier objet soigné. Si vous n'aviez pas à transmettre des choses, le compilateur produirait un fichier objet qui devrait contenir des informations sur toutes les suppositions possibles quant à ce que pourrait être la fonction 'add'. Et l'éditeur de liens devrait contenir une logique très intelligente pour essayer de déterminer quel 'ajout' vous voulez réellement appeler, quand la fonction 'add' peut vivre dans un fichier objet différent que le linker rejoint avec celui qui utilise add pour produire un DLL ou un exe. Il est possible que l'éditeur de liens ait un mauvais ajout. Supposons que vous vouliez utiliser int add (int a, float b), mais que vous ayez accidentellement oublié de l'écrire, mais l'éditeur de liens a trouvé un int déjà existant (int a, int b) et a pensé que c'était le bon. Votre code compilerait, mais ne ferait pas ce que vous attendiez. Donc, juste pour garder les choses explicites et éviter les devinettes etc, le compilateur insiste pour que vous déclariez tout avant de l'utiliser.
différence entre la déclaration et la définition
En aparté, il est important de connaître la différence entre une déclaration et une définition. Une déclaration donne juste assez de code pour montrer à quoi ressemble quelque chose, donc pour une fonction, c'est le type de retour, la convention d'appel, le nom de la méthode, les arguments et leurs types. Mais le code de la méthode n'est pas requis. Pour une définition, vous avez besoin de la déclaration, puis aussi du code de la fonction.
Comment l'avant-déclarations peuvent considérablement réduire le temps de construction
Vous pouvez obtenir la déclaration d'une fonction dans votre .cpp ou le fichier .h par # includ'ing l'en-tête qui contient déjà une déclaration de la fonction. Cependant, cela peut ralentir votre compilation, surtout si vous #incluez un en-tête dans un .h au lieu de .cpp de votre programme, car tout ce qui #inclut le .h que vous écrivez finirait par # inclure tous les en-têtes. tu as écrit #includes aussi. Soudainement, le compilateur a inclus # les pages et les pages de code qu'il doit compiler même si vous vouliez seulement utiliser une ou deux fonctions. Pour éviter cela, vous pouvez utiliser une déclaration forward et taper vous-même la déclaration de la fonction en haut du fichier. Si vous n'utilisez que quelques fonctions, cela peut vraiment rendre vos compilations plus rapides par rapport à toujours #including l'en-tête. Pour les projets de très grande taille, la différence pourrait être d'une heure ou plus de temps de compilation réduit à quelques minutes.
références cycliques Break où deux définitions utilisent tous deux les uns des autres
En outre, les déclarations prévisionnelles peuvent vous aider à briser les cycles. C'est là que deux fonctions essayent de s'utiliser l'une l'autre. Quand cela arrive (et c'est une chose parfaitement valide à faire), vous pouvez #include un fichier d'en-tête, mais ce fichier d'en-tête essaie #include le fichier d'en-tête que vous écrivez actuellement .... qui #include l'autre en-tête , qui inclut # celui que vous écrivez. Vous êtes coincé dans une situation de poule et d'oeuf avec chaque fichier d'en-tête essayant de re # inclure l'autre. Pour résoudre ce problème, vous pouvez déclarer les pièces dont vous avez besoin dans l'un des fichiers et laisser le #include hors de ce fichier.
Par exemple:
Fichier Car.h
#include "Wheel.h" // Include Wheel's definition so it can be used in Car.
#include <vector>
class Car
{
std::vector<Wheel> wheels;
};
Fichier Wheel.h
Hmm ... la déclaration de voiture est nécessaire ici que la roue a un pointeur vers un Car, mais Car.h ne peut pas être inclus ici car cela entraînerait une erreur de compilation. Si Car.h était inclus, cela essaierait alors d'inclure Wheel.h qui inclurait Car.h qui inclurait Wheel.h et cela continuerait pour toujours, ainsi le compilateur génère une erreur. La solution est de transmettre voiture au lieu de déclarer:
class Car; // forward declaration
class Wheel
{
Car* car;
};
Si la roue de classe avait des méthodes qui ont besoin d'appeler des méthodes de voiture, ces méthodes pourraient être définies dans Wheel.cpp et Wheel.cpp est maintenant en mesure d'inclure Car.h sans provoquer de cycle.
Une « déclaration avant » est vraiment juste une déclaration. Voir (la fin de) cette réponse: http://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration/1410632#1410632 – sbi