2010-07-29 9 views
1

Voici le scénario. Nous utilisons Visual C++ 9. Il existe une bibliothèque C++ destinée à être utilisée par de nombreuses autres bibliothèques. Son interface est dans un en-tête:Comment conserver une définition constante dans un fichier d'en-tête et ne pas la lier dans chaque bibliothèque?

#pragma once 

//CommonLibraryHeader.h 
CSomeClass GetSomeClassFunction(); //is defined in some .cpp file 
const CSomeClass MagicValue(100, 200); //some predefined value that the previous function retuns to signify something important 

maintenant la bibliothèque est intégrée dans un fichier .dll. Le fichier d'en-tête est publié dans un emplacement commun et inclus dans plusieurs autres bibliothèques. Ces bibliothèques sont construites dans leurs fichiers .dll.

Le résultat net est le suivant. Comme chaque fichier .dll est un module exécutable séparé, il doit conserver toutes ces constantes. Chaque "constante" est en fait une instance d'une classe avec un constructeur non-trivial et un destructeur. Maintenant chaque .dll a une copie de MagicValue et le code pour la construction et la destruction de la variable est injecté dans chaque fichier .dll qui ajoute au temps de chargement et gonfle les fichiers .dll considérablement si la même chose arrive pour de nombreuses constantes.

La solution possible consiste à marquer la constante extern et à déplacer la définition dans un fichier .cpp. Mais alors les valeurs constantes passées dans le constructeur ne sont pas immédiatement visibles par le lecteur humain du fichier d'en-tête. On pourrait y ajouter un commentaire sur ce que sont les valeurs, mais comme d'habitude, nous devrions garder le commentaire en phase avec le code actuel.

Existe-t-il une meilleure solution - sans déplacer les constantes de l'en-tête et sans injecter le code de construction/destruction dans chaque fichier .dll?

Répondre

2

Vous pouvez utiliser l'astuce souvent utilisée avec les DLL qui exportent des classes et des fonctions: utilisez un #define défini uniquement lorsque la DLL que vous voulez inclure le code est construite, mais pas définie dans les autres, et faites un #if qui appelle le constructeur ou le définit comme extern, selon le cas.

+0

Fonctionnera, mais l'en-tête deviendra un désordre. – sharptooth