为什么不将操作符重载标记为内联会导致重复定义错误?
Why does this not marking an operator overload as inline cause a duplicate definition error?
创建以下类后,编译失败,出现许多"重复符号"错误。实际的错误并不是很具有描述性:
"重复符号__Zeq.... .://图书馆/开发/上的用户名都用户/dangillmor Xcode/DerivedData/MyProject-asdfasfasdf…/构建/中间体/MyProject.build Debug-iphonesimulator/MyTarget.build Objects-normal/i386/MyClass.o"
上面相同的消息出现在许多不同的类中,并且在编译结束时出现,所以我不知道问题是什么。
我检查了以下内容:
- 使用这个的类,包括Listening.hpp文件。这个类的唯一定义在这个文件中。
是什么问题呢?
#ifndef Listening_hpp
#define Listening_hpp
#include <stdio.h>
#include "EAction.hpp"
class Listening{
private:
int _emitterId;
int _listenerId;
std::string _eventName;
EAction* _actionToTake; //not owned.
protected:
public:
Listening(int emitterId,int listenerId,std::string eventName,EAction* actionToTake) : _emitterId(emitterId),_listenerId(listenerId),_eventName(eventName){
_actionToTake = actionToTake;
}
int getEmitterId()const{
return _emitterId;
}
int getListenerId()const{
return _listenerId;
}
std::string getEventName()const{
return _eventName;
}
EAction* getAction()const{
return _actionToTake;
}
};
bool operator==(const Listening &first,const Listening &other)
{
bool result = false;
if(first.getEmitterId() == other.getEmitterId()){
if(first.getListenerId() == other.getListenerId()){
if(first.getEventName() == other.getEventName()){
if (first.getAction() == other.getAction()) {
result = true;
}
}
}
}
return result;
}
bool operator!=(const Listening &first,const Listening &other)
{
bool result = !(first == other);
return result;
}
#endif /* Listening_hpp */
EAction.hpp
#ifndef EAction_hpp
#define EAction_hpp
#include <stdio.h>
class EAction{
private:
protected:
public:
virtual std::vector<std::size_t> seedList() = 0;
};
#endif /* EAction_hpp */
编辑:编辑标题-我认为这可能有助于那些因为其他原因而有重复定义错误的人忽略这个答案。
头文件中的自由函数必须标记为inline
,或者更改为仅在头文件中声明:
inline bool operator==(const Listening &first,const Listening &other)
{
, operator!=
也类似。
原来的问题是,任何单位包括这个头文件将有它的目标文件包含一个副本的operator==
。然后链接器看到这个,不知道哪一个是正确的。inline
可以被认为是一个链接指令,说"所有这些函数都是相同的,只是选择一个"。链接到更详细的答案。
同样的问题不会发生在类成员函数体中,因为在类定义内部编写的这些体是隐式的inline
。
历史注释:最初,inline
主要是一个优化指令。然而,现在的编译器足够聪明,可以自己做出优化决策;因此,inline
现在的主要用途是曾经的次要效果:避免在头文件中使用函数时出现多个定义错误。
顺便说一句,你可以写return bla;
,而不是把bla
赋值给bool
变量,等等。
相关文章:
- 使用命名空间时出现多个定义错误
- 对C宏的未定义引用,但在定义它时会出现重新定义错误
- 尝试调用 .h 文件中定义的变量时出现变量未定义错误
- 在头文件和 cpp 文件中使用一次 #pragma 时出现结构重定义错误
- 链接阶段出现多重定义错误
- 避免模板类中的重定义错误
- 即使我没有包含多个文件,C++中的多个定义错误
- 跨多个类的全局变量而不会出现重定义错误?
- 尝试运行 wasm 函数时出现模块未定义错误
- C++ 预期的左大括号以及重定义错误
- C++:成员的越界声明必须是纯虚函数的定义错误
- c++中数组的未定义错误
- Visual C:模板类中的自定义错误消息
- 为什么C++模板不会导致多个定义错误?
- 只有一个定义/声明时标头声明变量的多堆定义错误
- C++ 在多个其他类中使用单个类 - 编译时出现多个定义错误
- 基类未定义.错误 C2504
- Q 斯坦达项重定义错误
- 可视化C++中的结构定义错误
- VC++ C2011 重定义错误 - 未使用的头文件