有些学术问题,但我在编写一些单元测试时遇到了这个问题。
我的单元测试框架(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),当你使用相同的名称命名fixture结构时(现在结构的两个版本存在同名),然后其中一个版本是静默的抛出。这是非常令人惊讶的,因为我将我的编译器设置为/ W4(最高警告级别)并且没有出现警告。我想这是一个名称冲突,为什么命名空间被发明,但我真的需要将每个单元测试装置包装在一个单独的命名空间中吗?我只是想确保我没有错过更基本的东西。
有没有更好的方法来解决这个问题 - 这应该发生吗?我不应该看到重复的符号错误或什么?
答案 0 :(得分:8)
尝试将这些类放在匿名命名空间中,您可能会发现它不如为每个文件创建和命名新命名空间那么令人反感。
无法访问VS2005和Cpp单元,但这可能有效..
//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)
{
...
}
答案 1 :(得分:2)
编译器一次只能在一个编译单元上工作;这将是源文件和#includes的任何内容。由于您的类在不同的文件中,因此没有冲突。
链接器将所有内容放在一起,但它不知道类定义,所以它也没有看到冲突。
回到C的时代,链接器通常会认识到您有两个具有相同名称的不同函数并生成错误消息。使用C ++中的内联函数和模板,它不能再这样做了 - 不同的编译单元通常包含相同函数的副本,因此链接器只是假设它们是相同的。
答案 2 :(得分:0)
这基本上是因为需要在头文件中定义类,这导致在每个目标文件中具有类的冗余定义。因此,可以处理C ++链接的链接器必须将多余的类声明折叠在一起并假装该类只被声明一次。
链接器没有任何方法可以区分多个对象中包含的单个类和多个对象中具有相同名称的多个类。
你必须使用命名空间(或更好的语言)来解决这个问题。