大家好!
请考虑以下代码的和平:
$ cat a.cpp
#include <stdio.h>
struct A
{
void foo() { printf("a.cpp: A::foo()\n");}
};
void fooA()
{
A a;
a.foo();
}
$ cat b.cpp
#include <stdio.h>
struct A
{
void foo() { printf("b.cpp: A::foo()\n");}
};
void fooB()
{
A a;
a.foo();
}
$ cat main.cpp
void fooA();
void fooB();
int main()
{
fooA();
fooB();
return 0;
}
$ g++ main.cpp a.cpp b.cpp
$ ./a.out
a.cpp: A::foo()
a.cpp: A::foo()
正如您所看到的,链接器没有警告或错误,但在运行时我们收到的不是我们所期望的。我在gcc 4.8.1和msvc 2013上查看它。 使用简单的自由函数链接器会在这种情况下引发错误。但如果它是一个类的方法,它就不会。
为什么它会像这样?
答案 0 :(得分:3)
在类定义中定义的函数是隐式内联的,因此您可以在多个翻译单元中定义它们。
定义必须相同,但编译器不需要诊断,因为在一次处理一个单元时不可能。你打破了这个规则,给出了未定义的行为。
要为不同翻译单元中的不同实体使用相同的名称,您可以将每个名称放在不同的名称空间中,或者将一个未命名的名称空间放在翻译单元的本地名称空间中:
namespace /* optional name */ {
class A {
// whatever you want
};
}