sea*_*ges 2 c++ linker operator-overloading
我偶然发现了一个我可以解决的问题,但我不确定它为什么不起作用.
这是我试图使用的代码.为了简洁起见,已经剥离了字段.让我知道他们是否需要,我会把它们放回去:
#pragma once
#ifndef __PageStyle__
#define __PageStyle__
class PageStyle
{
public:
friend bool operator<(const PageStyle& lhs, const PageStyle& rhs);
};
bool operator<(const PageStyle& lhs, const PageStyle& rhs)
{
return (lhs.name < rhs.name);
}
#endif
Run Code Online (Sandbox Code Playgroud)
在我的源文件中,我做了类似这样的事情:
#include "PageStyle.h"
...
void PageStyleManager::loadPageStyles() {
std::set<PageStyle> pageStyles;
...
}
Run Code Online (Sandbox Code Playgroud)
编译好的代码,但链接器吐了出来:
1>PageStyleManager.obj : error LNK2005: "bool __cdecl operator<(class PageStyle const &,class PageStyle const &)" (??M@YA_NABVPageStyle@@0@Z) already defined in BaseContentFiller.obj
Run Code Online (Sandbox Code Playgroud)
BaseContentFiller是PageStyleManager的基类,也是以类似方式使用PageStyle的其他类.
经过深入研究后,我发现为了我的目的(使用STL集中的类)我毕竟不需要非成员朋友版本.我让操作员成为一个内联的公共成员,并且代码链接没有问题.
为什么会出现这个问题?我确保我使用过标题保护,这是我第一次遇到运算符重载的真实体验,我想知道我做错了什么.
Alo*_*ave 11
如果在头文件中包含函数的定义,则会在包含头文件的每个转换单元中定义它.
这违反了One Definition Rule,因此违反了链接器错误.
请注意,标题保护或#pragma once仅阻止相同的头文件多次包含在同一源文件中,但不会在不同的TU中定义它.
有两种解决方案可以解决问题:
cpp文件或 inline.不要operator<在头文件中定义; 只需在那里声明它,并在.cpp文件中定义它.#pragma once只是保持头文件不会被多次包含在同一个.cpp文件中,但它可能包含在不同的.cpp文件中,在这种情况下链接器将看到多个定义operator<.