Domanda

Un po 'di una questione accademica, ma mi sono imbattuto in questo durante la scrittura di alcuni test di unità.

Il mio framework di unit test (unittest ++) permette di creare le strutture per servire come infissi. Di solito questi sono personalizzati per i test nel file, così li ho messi nella parte superiore del mio file di unit test.

//Tests1.cpp

struct MyFixture {  MyFixture() { ... do some setup things ...} };

TEST_FIXTURE(MyFixture, SomeTest)
{
  ...
} 

//Tests2.cpp

struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}};

 TEST_FIXTURE(MyFixture, SomeOtherTest)
 {
  ...
 }

Tuttavia, ho trovato di recente (con VS2005 almeno) che quando si nome struct dispositivo utilizzando lo stesso nome (così ora esistono due versioni del struct con lo stesso nome), quindi una delle versioni è in silenzio buttato fuori . Questo è abbastanza sorprendente, perché ho il mio compilatore impostato / W4 (più alto livello di allarme) e nessun avvertimento viene fuori. Credo che questo è uno scontro nome, e perché gli spazi dei nomi sono stati inventati, ma ne ho veramente bisogno per avvolgere ciascuno dei miei unitari attrezzature di prova in uno spazio dei nomi separata? Voglio solo assicurarmi che non mi manca qualcosa di più fondamentale.

C'è un modo migliore per risolvere questo problema - questo dovrebbe accadere? Non dovrei essere vedendo un errore di simboli duplicati o qualcosa del genere?

È stato utile?

Soluzione

Prova attaccare le classi in un namespace anonimo, può risultare meno sgradevole di dover creare e nominare un nuovo spazio dei nomi per ogni file.

Non ho accesso all'unità VS2005 e Cpp, ma questo può funzionare ..

//Tests1.cpp
namespace
{
struct MyFixture {  MyFixture() { ... do some setup things ...} };
}

TEST_FIXTURE(MyFixture, SomeTest)
{
  ...
} 


//Tests2.cpp
namespace
{
struct MyFixture { MyFixture() { ... do some other setup things, different from Tests1}};
}

TEST_FIXTURE(MyFixture, SomeOtherTest)
{
 ...
}

Altri suggerimenti

Il compilatore funziona solo su una singola unità di compilazione in un momento; questo sarebbe il file di origine e qualsiasi cosa #includes. Dal momento che le classi sono in file diversi, nessun conflitto lì.

Il linker mette tutto insieme, ma non sa di definizioni di classe in modo che non vede un conflitto sia.

Torna nei giorni di C, era abbastanza comune per il linker di riconoscere che hai avuto due funzioni diverse con lo stesso nome e genera un messaggio di errore. Con funzioni inline e modelli in C ++, non può farlo più -. Diverse unità di compilazione spesso contenere duplicati della stessa funzione, in modo che il linker solo assume sono la stessa

Questo è fondamentalmente una conseguenza del fatto che le classi devono essere definite in file di intestazione, che porta ad avere definizioni ridondanti della classe in ciascun file oggetto. Quindi, un linker in grado di gestire C ++ legame deve piegare dichiarazioni di classe ridondanti insieme e far finta che la classe è stato dichiarato solo una volta.

Non c'è alcun modo per il linker di distinguere tra una singola classe incluso in oggetti multipli e classi multiple con lo stesso nome in più oggetti.

È necessario utilizzare gli spazi dei nomi (o un linguaggio migliore), per aggirare questo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top