Pergunta

Um pouco de uma pergunta acadêmica, mas eu encontrei isso enquanto escrevi alguns testes de unidade.

Minha estrutura de teste de unidade (unittest ++) permite criar estruturas para servir como acessórios. Geralmente, eles são personalizados para os testes no arquivo, então eu os coloco na parte superior do meu arquivo de teste de unidade.

//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)
 {
  ...
 }

No entanto, encontrei recentemente (pelo menos com o VS2005) que quando você nomeia a estrutura do equipamento usando o mesmo nome (então agora duas versões da estrutura existem com o mesmo nome), então Uma das versões é lançada silenciosamente. Isso é bastante surpreendente, porque tenho meu compilador definido para /W4 (nível de aviso mais alto) e nenhum aviso será lançado. Eu acho que este é um confronto de nome e por que os namespaces foram inventados, mas eu realmente preciso envolver cada um dos meus acessórios de teste de unidade em um espaço de nome separado? Eu só quero ter certeza de que não estou perdendo algo mais fundamental.

Existe uma maneira melhor de consertar isso - isso deveria estar acontecendo? Eu não deveria estar vendo um erro de símbolos duplicados ou algo assim?

Foi útil?

Solução

Tente enfiar as classes em um espaço para nome anônimo, você pode achar menos desagradável do que ter que criar e nomear um novo espaço para cada arquivo.

Não tem acesso à unidade VS2005 e CPP, mas isso pode funcionar.

//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)
{
 ...
}

Outras dicas

O compilador funciona apenas em uma única unidade de compilação por vez; Este seria o arquivo de origem e qualquer coisa #includes. Como suas aulas estão em arquivos diferentes, nenhum conflito lá.

O vinculador reúne tudo, mas não sabe sobre as definições de classe, por isso também não vê um conflito.

Nos dias de C, era bastante comum o vinculador reconhecer que você tinha duas funções diferentes com o mesmo nome e gerar uma mensagem de erro. Com funções e modelos embutidos no C ++, ele não pode mais fazer isso - unidades de compilação diferentes geralmente contêm duplicatas da mesma função; portanto, o vinculador apenas assume que eles são iguais.

Isso é basicamente uma conseqüência do fato de que as classes precisam ser definidas nos arquivos de cabeçalho, o que leva a definições redundantes da classe em cada arquivo de objeto. Portanto, um vinculador que pode lidar com a ligação C ++ precisa dobrar as declarações de classe redundantes juntas e fingir que a classe foi declarada apenas uma vez.

Não há como o vinculador distinguir entre uma única classe incluída em vários objetos e várias classes com o mesmo nome em vários objetos.

Você precisa usar namespaces (ou um idioma melhor), para contornar isso.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top