Doit-on utiliser de l'avant déclarations au lieu de comprend dans la mesure du possible?
Non, explicite sa déclaration ne devrait pas être considérée comme une ligne directrice générale. Avant les déclarations sont essentiellement des copier-collé, ou mal orthographié code, qui, dans le cas où vous trouvez un bug, faut fixes partout la déclaration sont utilisés. Cela peut être source d'erreurs.
Pour éviter les décalages entre le "avant" les déclarations et les définitions, mettre des déclarations dans un fichier d'en-tête et inclure que les fichiers d'en-tête à la fois la définition et à la déclaration, à l'aide de fichiers source.
Dans ce cas particulier, cependant, où opaque classe est à l'avant-déclarée, cette déclaration peut être acceptable d'utiliser, mais en général, à "utiliser la déclaration au lieu de comprend la mesure du possible", comme le titre de ce fil dit, peut être très risqué.
Voici quelques exemples de "invisible risques" en matière de déclaration (invisible risques = déclaration de l'inadéquation qui ne sont pas détectées par le compilateur ou l'éditeur de liens):
Explicite de l'avant les déclarations de symboles représentant les données peuvent être dangereux, parce que de telles déclarations peuvent nécessiter de connaissance de l'empreinte (taille) du type de données.
Explicite de l'avant les déclarations de symboles représentant les fonctions peuvent également être dangereux, comme les types de paramètres et le nombre de paramètres.
L'exemple ci-dessous illustre, par exemple, deux dangereux en avant les déclarations de données, ainsi que d'une fonction:
Fichier un.c:
#include <iostream>
char data[128][1024];
extern "C" void function(short truncated, const char* forgotten) {
std::cout << "truncated=" << std::hex << truncated
<< ", forgotten=\"" << forgotten << "\"\n";
}
Fichier b.c:
#include <iostream>
extern char data[1280][1024]; // 1st dimension one decade too large
extern "C" void function(int tooLarge); // Wrong 1st type, omitted 2nd param
int main() {
function(0x1234abcd); // In worst case: - No crash!
std::cout << "accessing data[1270][1023]\n";
return (int) data[1270][1023]; // In best case: - Boom !!!!
}
Compiler le programme avec g++ 4.7.1:
> g++ -Wall -pedantic -ansi a.c b.c
Note: Invisible danger, puisque g++ donne pas de compilateur ou l'éditeur de liens erreurs/avertissements
Remarque: en Omettant extern "C"
conduit à une erreur de couplage pour function()
en raison du c++ name mangling.
L'exécution du programme:
> ./a.out
truncated=abcd, forgotten="♀♥♂☻"
accessing data[1270][1023]
Segmentation fault