C ++ / VS2005: определение одного и того же имени класса в двух разных файлах .cpp - PullRequest
3 голосов
/ 16 января 2010

В некотором смысле академический вопрос, но я столкнулся с этим при написании некоторых модульных тестов.

Моя инфраструктура модульного тестирования (UnitTest ++) позволяет создавать структуры, служащие в качестве приборов. Обычно они настраиваются для тестов в файле, поэтому я помещаю их в начало моего файла модульных тестов.

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

Однако недавно я обнаружил (по крайней мере с VS2005), что когда вы называете структуру фикстура, используя одно и то же имя (так что теперь две версии структуры существуют с одинаковым именем), тогда одна из версий молча выброшен . Это довольно удивительно, потому что мой компилятор установлен на / W4 (самый высокий уровень предупреждения), и предупреждение не выдается. Я предполагаю, что это конфликт имен, и почему были изобретены пространства имен, но нужно ли мне оборачивать каждое из моих модульных тестовых устройств в отдельное пространство имен? Я просто хочу убедиться, что я не пропускаю что-то более фундаментальное.

Есть ли лучший способ исправить это - должно ли это происходить? Разве я не вижу ошибку повторяющихся символов или что-то в этом роде?

Ответы [ 3 ]

8 голосов
/ 16 января 2010

Попробуйте поместить классы в анонимное пространство имен, вы можете найти его менее неприятным, чем создание и присвоение имени новому пространству имен для каждого файла.работа ..

//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)
{
 ...
}
2 голосов
/ 16 января 2010

Компилятор работает только на одном модуле компиляции одновременно; это будет исходный файл и все, что оно включает. Поскольку ваши классы находятся в разных файлах, здесь нет конфликтов.

Компоновщик собирает все вместе, но он не знает об определениях классов, поэтому не видит и конфликта.

В те времена, когда C работал с компоновщиком, было достаточно распознать, что у вас две разные функции с одним и тем же именем, и сгенерировать сообщение об ошибке. Со встроенными функциями и шаблонами в C ++ он больше не может этого делать - разные модули компиляции часто содержат дубликаты одной и той же функции, поэтому компоновщик просто предполагает, что они одинаковы.

0 голосов
/ 16 января 2010

Это в основном следствие того факта, что классы должны быть определены в заголовочных файлах, что приводит к избыточным определениям классов в каждом объектном файле. Таким образом, компоновщик, который может обрабатывать связи C ++, должен сложить избыточные объявления класса и сделать вид, что класс был объявлен только один раз.

Компоновщик никак не может различить один класс, включенный в несколько объектов, и несколько классов с одинаковым именем в нескольких объектах.

Вы должны использовать пространства имен (или лучший язык), чтобы обойти это.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...