为什么这不会标记操作符重载,因为内联会导致重复的定义错误?

Kai*_*zay 5 c++ inline multiple-definition-error c++11

创建以下类后,编译失败,出现许多"重复符号"错误.实际错误不是很具描述性:

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

上面相同的消息出现在许多不同的类中,并出现在编译结束时,所以我不知道问题是什么.

我检查了以下内容:

  1. 使用它的类包括Listening.hpp文件.
  2. 此类的唯一定义是在此文件中.

问题是什么?

#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 */
Run Code Online (Sandbox Code Playgroud)

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 */
Run Code Online (Sandbox Code Playgroud)

编辑:编辑标题 - 我认为这可能会帮助那些因其他原因而出现重复定义错误的人忽略这个答案.

M.M*_*M.M 6

必须标记头文件中的自由函数inline,或者将其更改为仅在标头中包含声明:

inline bool operator==(const Listening &first,const Listening &other)
{
Run Code Online (Sandbox Code Playgroud)

并且类似地operator!=.

最初的问题是包含此头文件的任何单元都将使其目标文件包含该副本operator==.然后链接器会看到这一点,并且不知道哪一个是正确的.该inline可看作是一个连接指令说:"所有这些功能都是一样的,随便挑一个." 链接到更详细的答案.

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


历史记录:最初,inline主要是一个优化指令.然而,现在编译器足够智能,可以自己做出优化决策; 所以inline现在的主要用途是曾经的次要影响:在标题中有一个函数时避免多个定义错误.


顺便说一句,你可以写return bla;,而不是分配blabool变量等等.