2

在了解了更多关于类和指针的知识后,我重构了一个我拥有的程序并删除了超过 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 的文件(嗯,其他文件包括piece.h 间接来自包括piece.h 的位置),board.h 是唯一包含location.h 的文件,并且一堆类包括board.h

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

有趣的是,其中一个错误有一个“in function 'OPiece':”,然后我的 IDE chatter.oputs

知道可能导致此重新定义错误的原因吗?

4

5 回答 5

4
  1. 重建一切
  2. 寻找 Piece::Piece,并从头文件 2b 中删除所有这些。从不 #include .cpp 文件
  3. 查找解析为 Piece 的#define
于 2010-10-29T17:34:39.513 回答
2

多函数定义错误的最常见原因是将函数定义放在头文件中而忘记创建它inline

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

于 2010-10-29T17:31:13.300 回答
1

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

于 2010-10-29T17:32:07.660 回答
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) {
}

但是,模板的定义不同。

该错误通常表明它Piece::Piece(int a) : d_a(a) {}包含在多个 cpp 文件中。

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

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

诊断此问题的一种快速方法是(假设您的构建不需要很长时间):

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

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

于 2010-10-29T17:53:44.630 回答
0

只是一个猜测:你使用过#include还是#import偶然使用过——我曾经发生过一次:-)

于 2010-10-29T17:34:12.510 回答