Pregunta

Un poco de una cuestión académica, pero me encontré con esto al escribir algunas pruebas unitarias.

Mi marco de pruebas unitarias (unittest ++) le permite crear estructuras para servir como accesorios. Por lo general, éstos son personalizados para las pruebas en el archivo, por lo que los pusieron en la parte superior de mi archivo de prueba de unidad.

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

Sin embargo, encontré recientemente (con VS2005 al menos) que cuando se nombra la struct accesorio utilizando el mismo nombre (por lo que ahora existen dos versiones de la struct con el mismo nombre), entonces una de las versiones es silencio expulsado . Esto es bastante sorprendente, porque tengo mi compilador establece en / W4 (el más alto nivel de aviso) y ninguna advertencia que sale. Supongo que esto es un conflicto de nombres, y por qué se inventaron los espacios de nombres, pero lo que realmente necesita para envolver cada una de mis accesorios de la prueba de la unidad en un espacio de nombres separado? Sólo quiero asegurarme de que no me falta algo más fundamental.

¿Hay una mejor manera de solucionar este problema - debe estar pasando esto? ¿No debería estar viendo un error de símbolos duplicados o algo?

¿Fue útil?

Solución

Intente meter las clases en un espacio de nombres en el anonimato, puede que le resulte menos desagradable que tener que crear y nombrar un nuevo espacio de nombres para cada archivo.

No tienen acceso a la unidad de VS2005 y CPP, pero esto puede 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)
{
 ...
}

Otros consejos

El compilador sólo funciona en una única unidad de compilación a la vez; este sería el archivo de origen y cualquier cosa que #Includes. Debido a que sus clases son en diferentes archivos, no hay conflicto allí.

El enlazador pone todo junto, pero no sabe nada de las definiciones de clase para que no se vea un conflicto tampoco.

En los días de C, era bastante común para el enlazador de reconocer que tenía dos funciones diferentes con el mismo nombre y generar un mensaje de error. Con funciones en línea y plantillas en C ++, no puede hacer eso -. Diferentes unidades de compilación menudo contendrán duplicados de la misma función, por lo que el enlazador simplemente asume que son la misma

Esto es básicamente una consecuencia del hecho de que las clases deben ser definidos en los archivos de cabecera, lo que lleva a tener definiciones redundantes de la clase en cada fichero objeto. Por lo que un enlazador que puede manejar vinculación C ++ tiene que doblar las declaraciones de clase redundantes entre sí y pretender que la clase fue declarado sólo una vez.

No hay ninguna manera por el enlazador para distinguir entre una sola clase incluido en múltiples objetos y múltiples clases con el mismo nombre en varios objetos.

Usted tiene que usar espacios de nombres (o mejor un idioma), para evitar esto.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top