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

时间:2016-09-07 03:42:57

标签: c++ c++11 inline multiple-definition-error

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

  

"重复符号__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. 此类的唯一定义是在此文件中。
  3. 问题是什么?

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

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

1 个答案:

答案 0 :(得分:6)

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

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

,同样适用于operator!=

最初的问题是包含此头文件的任何单元都将使其目标文件包含operator==的副本。然后链接器会看到这个,并且不知道哪一个是正确的。 inline可以被认为是一个链接器指令来说&#34;所有这些功能是相同的,只需选择一个&#34;。 Link to more detailed answers.

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

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

顺便说一句,您可以撰写return bla;,而不是将bla分配给bool变量,依此类推。