多次重新定义错误

时间:2010-10-29 17:24:50

标签: c++ class header redefinition

在详细了解了类和指针之后,我重构了一个程序并将其删除了> 200行代码,在创建另外两个类LocationPiece的过程中。问题是,在编译完所有内容之后,链接器会抱怨Piece的构造函数被多次定义,并带有一堆错误:

In function 'Piece':                                         board.o
multiple definition of 'Piece::Piece(int)`                   char_traits.h
In function 'Piece':                                         board.o
multiple definition of 'Piece::Piece(int)`                   piece.cpp
In function 'Piece':                                         player.o
multiple definition of 'Piece::Piece(int)`                   piece.cpp
In function 'Piece':                                         player.o
multiple definition of 'Piece::Piece(int)`                   piece.cpp (yes, same exact error!)
In function 'Piece':                                         refereee.o
multiple definition of 'Piece::Piece(int)`                   char_traits.h
In function 'Piece':                                         referee.o
multiple definition of 'Piece::Piece(int)`                   piece.cpp
...

当我点击char_traits.h的错误时,它会让我知道:

static size_t
length(const char_type* __s) //error points here to line 262
{ return __builtin_strlen(__s); }

另一个char_traits.h带我到

  static int
  compare(const char_type* __s1, const char_type* __s2, size_t __n) //line 258, error points here too
  { return __builtin_memcmp(__s1, __s2, __n); }

而且你知道,location.h是唯一包含piece.h的东西(好吧,其他文件包括part.h间接来自包括piece.h的位置),board.h是唯一包含location的东西。 h,一堆类包括board.h

我尝试将标题保护更改为_OTHELLO_PIECE_H,并尝试将该类重命名为OPiece(通过IDE)。既没有解决问题。

有趣的是,其中一个错误有一个“在函数中'OPiece':”,之后我的IDE放了chatter.o,即使chatter.h和chatter.cpp都不包含任何包含OPiece的内容

知道可能导致此重定义错误的原因是什么?

5 个答案:

答案 0 :(得分:4)

  1. 重建一切
  2. 查找Piece :: Piece,并从头文件中删除所有这些内容 2B。永远不要#include .cpp文件
  3. 查找解析为Piece
  4. 的#define

答案 1 :(得分:2)

多功能定义错误的最常见原因是将函数定义放在头文件中而忘记将其设为inline

我不会担心char_traits.h - 这可能意味着由于某些模板运行,链接器无法找到一个更好的地方来声明在该特定目标文件中发生的定义。

答案 2 :(得分:1)

您应该将构造函数的实现放在piece.cpp中,而不是直接放在piece.h中。

答案 3 :(得分:1)

在典型构建中有两个地方可以实现Piece::Piece(int)

1)界面(声明时)

class Piece {
    int d_a;
public:
    Piece(int a) : d_a(a) {
    }
    /* ... */
};

2)在专用的cpp文件中

在Piece.hpp中

class Piece {
    int d_a;
public:
    Piece(int a);
    /* ... */
};

在Piece.cpp中

Piece::Piece(int a) : d_a(a) {
}

但是,模板的定义不同。

错误通常表示{c}文件中包含Piece::Piece(int a) : d_a(a) {}

生成的每个目标文件都会在可见的位置添加符号Piece::Piece(int)

在构建结束时,所有对象都被合并/链接以创建最终的二进制文件或可执行文件。然后链接器会看到有这个定义的副本并产生错误。

诊断这一点的一种快速方法是(假设你的构建不需要很长时间):

#warning Piece::Piece(int) is visible here
Piece::Piece(int a) : d_a(a) {
}

应该发出一个警告。如果发出更多,则编译器可能会提供一些信息(例如包含顺序)。

答案 4 :(得分:0)

猜测一下:您是否使用过#include或偶然使用过#import - 这件事发生在我身上一次: - )