[英]Friend operator overloading causes “already defined in” linker errors
我偶然发现了一个我可以解决的问题,但我不确定它为什么不起作用。
这是我试图使用的代码。 为了简洁起见,已经剥离了字段。 让我知道他们是否需要,我会把它们放回去:
#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
在我的源文件中,我做了类似这样的事情:
#include "PageStyle.h"
...
void PageStyleManager::loadPageStyles() {
std::set<PageStyle> pageStyles;
...
}
编译好的代码,但链接器吐了出来:
1>PageStyleManager.obj : error LNK2005: "bool __cdecl operator<(class PageStyle const &,class PageStyle const &)" (??M@YA_NABVPageStyle@@0@Z) already defined in BaseContentFiller.obj
BaseContentFiller是PageStyleManager的基类,也是以类似方式使用PageStyle的其他类。
经过深入研究后,我发现为了我的目的(在STL集中使用类)我毕竟不需要非成员朋友版本。 我让操作员成为一个内联的公共成员,并且代码链接没有问题 。
为什么会出现这个问题? 我确保我使用过标题保护,这是我第一次遇到运算符重载的真实体验,我想知道我做错了什么。
如果在头文件中包含函数的定义,则会在包含头文件的每个转换单元中定义它。
这违反了One Definition Rule ,因此违反了链接器错误。
请注意,标题保护或#pragma once
只是阻止相同的头文件多次包含在同一源文件中,但不能在不同的TU中定义它。
有两种解决方案可以解决问题:
cpp
文件中添加定义 inline
。 不要在头文件中定义operator<
; 只需在那里声明它,并在.cpp
文件中定义它。 #pragma once
只是让头文件在同一个.cpp
文件中多次被包含,但它可能包含在不同的.cpp
文件中,在这种情况下,链接器将看到operator<
多个定义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.