我想在我的班级上使用binary_search,因此我定义了一个运算符<。当一切都在主文件中时它起作用,但是当我在另一个文件中编写类时,我得到了链接器错误。
显示问题的最简单的例子是 B.h:
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:已在Main.obj中定义的“bool __cdecl运算符&lt;(B类const&amp;,B类const&amp;)”(?? M @ YA_NABVB @@ 0 @ Z) :致命错误LNK1169:找到一个或多个多重定义的符号
如何解决?
答案 0 :(得分:3)
这是因为在头文件中未正确定义运算符。您需要将其设为inline
(或static
)。
如果不是inline
或static
,则会在包含头文件的每个源文件中定义该函数,从而导致多个定义错误。
答案 1 :(得分:2)
您在头文件中定义了运算符函数,这意味着包含它的每个.cpp文件都有自己的副本。您有两种可能的解决方案:
标记函数inline
。
将该功能移至.cpp文件
答案 2 :(得分:0)
未声明的函数inline
必须至多在一个翻译单元中定义。通过让B.cpp
和copntaining main()
文件包含B.h
标题,您可以获得两个定义。相反,如果你声明一个函数inline
,那么定义需要包含在每个使用它的翻译单元中,所以在标题中定义是正确的。
因此,如果您希望运算符的实现保留在标题中,则需要在其定义上使用inline
限定符 - 或者直接在class B
的定义内定义运算符,其中你宣布它是朋友。后者将隐含内联。
否则,您需要将运算符的定义移动到B.cpp
文件。