2017-10-13 10 views
1

J'ai un projet avec un tas de fichiers de test C++. Chaque fichier de test déclare une classe comme ceci:Comment isoler deux classes C++ avec le même nom?

// test1.cpp 
... 
class Foo { void bar() {...} }; 
... 

et

// test2.cpp 
... 
class Foo { void bar() {...} }; 
... 

et ainsi de suite. Tout allait bien jusqu'à ce que la suite de tests devienne assez grande et que le contenu de la classe Foo devienne différent dans certains modules de test. Les choses vont mal quand il s'agit de liaison. Les méthodes de la classe dans chaque fichier ELF sont déclarées en tant que symboles faibles publics (symboles "W" dans nm) et il en résulte l'appel d'instances incorrectes de la méthode, par ex. tests1.cpp appelle Foo::bar() à partir de tests2.cpp.

Comment isoler une instance de class Foo d'une autre?

En déclarant la classe avec __attributes__ ((visibility ("hidden"))) n'a pas aidé, les symboles restent publics.

Aussi, bien sûr, je peux utiliser des espaces de noms pour cela, mais je préfère éviter cette option.

Des idées?

+5

Pourquoi préféreriez-vous éviter les espaces de noms? C'est à peu près la raison pour laquelle ils ont été inventés! – Steve

+3

Vous pouvez utiliser des espaces de noms anonymes, Envelopper la déclaration 'Foo' dans un' namespace {class Foo {...}; } 'devrait fonctionner exactement de la même manière et rendre le' Foo' interne à l'unité de compilation. – rodrigo

+0

@Steve Je voudrais réparer les choses une fois (par exemple dans un makefile) plutôt que d'inventer chaque fois un nouveau nom pour un espace de noms. – krokoziabla

Répondre

7

La suspicion que vous avez avec les espaces de noms dans la mesure où vous ne voulez pas leur attribuer des noms arbitraires n'est pas fondée.

Ceci est un travail parfait pour espaces de noms anonymes. Ecrivez

namespace /*no name here makes it anonymous*/{ 
    class Foo { void bar() {...} }; 
} 

et ainsi de suite. Cela permet d'internaliser Foo à cette unité de traduction particulière.

+0

Eh bien, en utilisant des espaces de noms anonymes résoudre le problème. J'avais juste peur de ne pas pouvoir mettre un test GTest en un. Mais il semble que je peux ... Alors je devrais vous remercier. Mais ... Y at-il un moyen de le corriger non pas dans les sources mais sur le côté du compilateur? – krokoziabla

+0

@krokoziabla: Mes réserves en faisant cela est que vos fichiers source s'éloignent d'être directement compilable. Je souffrirais du texte supplémentaire si j'étais vous. – Bathsheba

+0

@krokoziabla - vous pourriez être en mesure de trouver un moyen d'utiliser un marteau pour conduire dans une vis, mais vous ferez mieux d'utiliser un tournevis. –