如果两个 C++ 文件对同名的类有不同的定义,那么当它们被编译和链接时,即使没有警告也会抛出一些东西。例如,
// a.cc
class Student {
public:
std::string foo() { return "A"; }
};
void foo_a()
{
Student stu;
std::cout << stu.foo() << std::endl;
}
// b.cc
class Student {
public:
std::string foo() { return "B"; }
};
void foo_b()
{
Student stu;
std::cout << stu.foo() << std::endl;
}
当使用 g++ 编译并链接在一起时,两者都将输出“A”(如果在命令行顺序中 a.cc 在 b.cc 之前)。
一个类似的话题是here。我看到命名空间会解决这个问题,但我不知道为什么链接器甚至没有发出警告。如果该类的一个定义具有另一个未定义的额外功能,则假设 b.cc 更新为:
// b.cc
class Student {
public:
std::string foo() { return "B"; }
std::string bar() { return "K"; }
};
void foo_b()
{
Student stu;
std::cout << stu.foo() << stu.bar() << std::endl;
}
然后 stu.bar() 效果很好。感谢任何可以告诉我编译器和链接器在这种情况下如何工作的人。
作为一个额外的问题,如果类是在头文件中定义的,是否应该总是用未命名的命名空间包装它们以避免这种情况?有没有副作用?