2017-10-13 8 views
1

Ich habe ein Projekt mit einer Reihe von C++ Testdateien. Jede Testdatei deklariert eine Klasse wie folgt:Wie isoliert man zwei C++ Klassen mit dem gleichen Namen?

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

und

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

und so weiter.

Alles war in Ordnung, bis die Testsuite ziemlich groß wurde und der Inhalt der Foo Klasse in einigen Testmodulen unterschiedlich wurde. Bei der Verknüpfung gehen die Dinge schief. Die Methoden der Klasse in jeder ELF-Datei werden als öffentliche schwache Symbole ("W" in nm Notation) deklariert, und dies führt zum Aufrufen falscher Instanzen der Methode, z. tests1.cpp ruft Foo::bar() von tests2.cpp.

Wie isoliert man eine Instanz von class Foo von einer anderen?

Die Deklaration der Klasse mit __attributes__ ((visibility ("hidden"))) hilft nicht, die Symbole bleiben öffentlich.

Auch sicher kann ich Namespaces dafür verwenden, aber ich möchte diese Option vermeiden.

Irgendwelche Ideen?

+5

Warum möchten Sie Namespaces lieber vermeiden? Es ist so ziemlich der Grund, warum sie erfunden wurden! – Steve

+3

Sie könnten anonyme Namespaces verwenden und die Deklaration 'Foo' in einen' Namespace {Klasse Foo {...}; } sollte genauso funktionieren und den 'Foo' intern zur Kompilierungseinheit machen. – rodrigo

+0

@Steve Ich möchte Dinge einmal beheben (z. B. in einem Makefile), anstatt jedes Mal einen neuen Namen für einen Namensraum zu erfinden. – krokoziabla

Antwort

7

Der Verdacht, den Sie mit Namespaces haben, insofern Sie diesen keine willkürlichen Namen zuordnen wollen, ist unbegründet.

Dies ist ein perfekter Job für anonyme Namespaces. Schreiben Sie

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

und so weiter. Dadurch wird Foo für diese bestimmte Übersetzungseinheit internalisiert.

+0

Nun, die Verwendung anonymer Namespaces löst das Problem. Ich hatte nur Angst, dass ich einen GTest-Test nicht in einen machen könnte. Aber es scheint, ich kann ... Also ich sollte dir danken. Aber ... Gibt es eine Möglichkeit, es nicht in den Quellen, sondern auf der Seite des Compilers zu reparieren? – krokoziabla

+0

@krokoziabla: Meine Vorbehalte dabei sind, dass Ihre Quelldateien nicht mehr direkt kompilierbar sind. Ich würde den zusätzlichen Text leiden, wenn ich du wäre. – Bathsheba

+0

@krokoziabla - Sie könnten vielleicht einen Weg finden, einen Hammer zum Eintreiben einer Schraube zu verwenden, aber mit einem Schraubenzieher sind Sie viel besser dran. –

Verwandte Themen