1

我想在我的班级上使用 binary_search,所以我定义了一个 operator<。当所有内容都在主文件中时它可以工作,但是当我在另一个文件中编写类时出现链接器错误。

显示问题的最简单示例是 Bh:

class B
{
public:
~B(void);
string b;
int v;
B(int val, string bb);
friend bool operator< (const B &lhs, const B &rhs);
 };

 bool operator< (const B &lhs, const B &rhs){
    return lhs.v < rhs.v;
};

B.cpp 只是定义了构造函数。主要是这样的:

#include "B.h"
int main( int argc, const char* argv[] )
{

vector<B> vec;
B a1(2, "gg");
B a2(4, "gdhd");
    vec.push_back(a2);
    vec.push_back(a1);
bool pos = binary_search(vec.begin(),vec.end(), B(2, "ghd"));
}

错误 LNK2005: "bool __cdecl operator<(class B const &,class B const &)" (??M@YA_NABVB@@0@Z) 已在 Main.obj 中定义:致命错误 LNK1169:一个或多个多重定义符号成立

如何解决?

4

3 回答 3

3

这是因为操作符在头文件中定义不正确。你需要做到inline(或static)。

如果不是inlinestatic,则函数将在包含头文件的每个源文件中定义,从而导致多个定义错误。

于 2013-04-30T08:45:08.400 回答
2

您在头文件中定义运算符函数,这意味着包含它的每个 .cpp 文件都有自己的副本。您有两种可能的解决方案:

  1. 标记功能inline

  2. 将函数移动到 .cpp 文件中

于 2013-04-30T08:45:49.753 回答
0

未声明的函数inline最多只能在一个翻译单元中定义。通过让包含标题B.cpp的文件main()包含B.h标题,您将获得两个定义。相反,如果您声明一个函数inline,则定义需要包含在使用它的每个翻译单元中,因此在标题中包含定义是正确的做法。

因此,如果您希望运算符的实现保留在标头中,则需要inline在其定义中使用限定符 - 或直接在定义中定义运算符class B,您将其声明为友元。后者将使其隐式内联。

否则,您需要将运算符的定义移动到B.cpp文件中。

于 2013-04-30T08:49:47.630 回答