After creating the following class, compilation fails with many "duplicate symbol" errors. The actual error is not very descriptive :
"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 "
The above same message appears for many different classes, and appears at the end of compilation, so I don't know what the problem is.
I have checked the following:
What can the problem be ?
#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 */
EDIT: Edited the title - I think this may help people who have a duplicate definition error for other reasons ignore this answer.
The free functions in the header file must either be marked inline
, or changed to have only declarations in the header:
inline bool operator==(const Listening &first,const Listening &other)
{
and similarly for operator!=
.
The original problem is that any unit including this header file will have its object file contain a copy of the operator==
. Then the linker sees this and doesn't know which one is meant to be the right one. The inline
can be thought of as a linker directive to say "All these functions are the same, just pick one". Link to more detailed answers.
The same problem didn't happen with the class member function bodies because such bodies written inside the class definition are implicitly inline
.
Historical note: Originally, inline
was primarily an optimization directive. However, nowdays compilers are smart enough to make optimization decisions on their own; so the primary use of inline
now is what was once the secondary effect: to avoid multiple definition errors when having a function in a header.
BTW, you can write return bla;
, instead of assigning bla
to a bool
variable and so on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With