为什么在两个不同的cpp文件中定义具有相同名称的类时没有链接器错误?

时间:2015-02-26 17:42:21

标签: c++ linker

大家好!

请考虑以下代码的和平:

   $ 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上查看它。 使用简单的自由函数链接器会在这种情况下引发错误。但如果它是一个类的方法,它就不会。

为什么它会像这样?

1 个答案:

答案 0 :(得分:3)

在类定义中定义的函数是隐式内联的,因此您可以在多个翻译单元中定义它们。

定义必须相同,但编译器不需要诊断,因为在一次处理一个单元时不可能。你打破了这个规则,给出了未定义的行为。

要为不同翻译单元中的不同实体使用相同的名称,您可以将每个名称放在不同的名称空间中,或者将一个未命名的名称空间放在翻译单元的本地名称空间中:

namespace /* optional name */ {
    class A {
        // whatever you want
    };
}