为什么这不会将运算符重载标记为内联导致重复定义错误?

Why does this not marking an operator overload as inline cause a duplicate definition error?

创建以下 class 后,编译失败并出现许多 "duplicate symbol" 错误。实际错误描述性不强:

"duplicate symbol __Zeq.... in : /Users/myusername/Library/Developer/Xcode/DerivedData/MyProject-asdfasfasdf..../Build/Intermediates/MyProject.build/Debug-iphonesimulator/MyTarget.build/Objects-normal/i386/MyClass.o "

上面同样的信息出现在很多不同的classes上,并且出现在编译结束的时候,所以我不知道是什么问题。

我检查了以下内容:

  1. 类 使用这个,包括 Listening.hpp 文件。
  2. 此 class 的唯一定义在此文件中。

可能是什么问题?

#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 */

编辑:编辑了标题 - 我认为这可能有助于因其他原因而出现重复定义错误的人忽略此答案。

header 文件中的自由函数必须标记为 inline,或者更改为仅在 header:

中声明
inline bool operator==(const Listening &first,const Listening &other)
{

operator!= 也类似。

最初的问题是任何包含此 header 文件的单元都将在其 object 文件中包含 operator== 的副本。然后链接器看到这个并且不知道哪个是正确的。 inline 可以被认为是表示 "All these functions are the same, just pick one" 的链接器指令。 Link to more detailed answers.

class 成员函数体没有发生同样的问题,因为写在 class 定义中的这些体是隐式的 inline.


历史记录: 最初,inline 主要是一个优化指令。然而,如今的编译器足够聪明,可以自行做出优化决策;所以 inline 现在的主要用途是曾经的次要效果:避免在 header.

中有一个函数时出现多重定义错误

顺便说一句,您可以编写 return bla; ,而不是将 bla 分配给 bool 变量等等。