J'ai une bibliothèque statique qui est générée à partir de plusieurs fichiers cpp sous linux en utilisant g++. Un fichier d'en-tête contient une classe qui implémente le modèle de la fabrique.
pseudo-code dans le fichier d'en-tête comme ci-dessous
class Factory
{
public:
static Factory& instance();
Base * create(const std::string& name);
template<class T>
void register_class(const std::string& name);
}
template <class T>
class FactoryRegister
{
public:
FactoryRegister(const std::string& name)
{
Factory::instance().register_class<T>(name);
}
}
Le fichier cpp pour Factory contient les implémentations. Dans un autre fichier cpp Derive.cpp, il y a une classe que je veux enregistrer dans Factory. et j'ai défini une variable globale pour le faire. le code est le suivant
FactoryRegister<Derive> g_register_derive("derive");
tous ces fichiers sont compilés dans une bibliothèque statique et sont liés à un exécutable.
Si je comprends bien, comme le g_register_derive n'est référencé par aucun code, il ne devrait pas être lié à l'exécutable à moins que l'option whole-archive soit fournie.
La partie étrange est que si je mets g_register_derive dans Derive.cpp, il est vrai que ce symbole n'est pas lié à l'exécutable. Mais si je mets g_register_derive dans Factory.cpp, il est lié à l'exécutable.
J'ai utilisé nm pour vérifier le résultat, et il y a aussi une ligne de code qui appelle Factory::instance().create("Derive")
qui peut aussi être utilisé pour vérifier si g_register_derive est lié ou non.
et bien sûr si je fournis l'option whole-archive, g_register_derive sera toujours lié à l'exécutable.