Reputation: 1332
I have two classes given following
FIRST CLASS:
=======================================
#ifndef SAPPOSITIONCLASS_HPP
#define SAPPOSITIONCLASS_HPP
#include "SapArchive.hpp"
class SapPositionClass
{
double md_latitude;
double md_longitude;
public:
SapPositionClass(double latitude,double longitude)
double GetLatitude() const;
double GetLongitude() const;
void SetPosition(double latitude,double longitude)
friend SapArchive& operator <<(SapArchive& stream,const SapPositionClass& obj);
friend SapArchive& operator >>(SapArchive& stream,SapPositionClass& obj);
~SapPositionClass();
};
SapArchive& operator <<(SapArchive& stream,const SapPositionClass& obj)
{
stream << obj.mush_Id << obj.msz_title << obj.md_latitude << obj.md_longitude << obj.msh_altitudeMeter;
return stream;
}
SapArchive& operator >>(SapArchive& stream,SapPositionClass& obj)
{
stream >> obj.mush_Id >> obj.msz_title >> obj.md_latitude >> obj.md_longitude >> obj.msh_altitudeMeter;
return stream;
}
#endif
SECOND CLASS:
=============================================
#define SAPMINEFIELDBREACHCLASSS_HPP
#include "SapEntityClass.hpp"
#include "SapPositionClass.hpp"
class SapMinefieldBreachClass
{
unsigned short mush_minefieldId;
QString msz_breachDescription;
SapPositionClass mobj_position;
public:
SapMinefieldBreachClass(unsigned short minefieldId,SapPositionClass position, QString description);
unsigned short GetMinefieldId() const;
QString GetBreachDescription() const;
void SetBreachDescription(const QString breachDescription);
SapPositionClass GetPosition() const;
void SetPosition(SapPositionClass position);
};
#endif
SAFE LANE CLASS
---------------------------
#ifndef SAPSAFELANECLASS_HPP
#define SAPSAFELANECLASS_HPP
#include "SapEntityClass.hpp"
#include "SapPositionClass.hpp"
class SapSafeLaneClass : public SapEntityClass
{
unsigned short mush_minefieldId;
QList<SapPositionClass> mobj_layoutPointList;
unsigned short mush_widthMeter;
public:
SapSafeLaneClass(unsigned short minefieldId,const unsigned short id,const QString title);
SapSafeLaneClass(unsigned short minefieldId,const unsigned short id,const QString title,unsigned short width,QList<SapPositionClass> layoutPointList)throw (SapArgumentNullException);
unsigned short GetMinefieldId() const;
unsigned short GetWidth() const;
QList<SapPositionClass> GetLayoutPointList() const;
void SetLayoutPointList(QList<SapPositionClass> layoutPointList) throw (SapArgumentNullException);
};
#endif
PROBLEM: when i compiling these classes i get following warning
SapSafeLaneClass.obj:-1: warning: LNK4006: "class SapArchive & __cdecl operator<<(class SapArchive &,class SapPositionClass const &)" (??6@YAAAVSapArchive@AAV3452@ABVSapPositionClass@012@@Z) already defined in SapMinefieldBreachClass.obj; second definition ignored
please help to avoid this warning....
Upvotes: 1
Views: 901
Reputation: 340218
Add the inline
keyword to your definitions of operator <<(SapArchive&,const SapPositionClass&)
and operator >>(SapArchive&,SapPositionClass&)
in SapPostionClass.hpp
:
inline
SapArchive& operator <<(SapArchive& stream,const SapPositionClass& obj)
{
stream << obj.mush_Id << obj.msz_title << obj.md_latitude << obj.md_longitude << obj.msh_altitudeMeter;
return stream;
}
inline
SapArchive& operator >>(SapArchive& stream,SapPositionClass& obj)
{
stream >> obj.mush_Id >> obj.msz_title >> obj.md_latitude >> obj.md_longitude >> obj.msh_altitudeMeter;
return stream;
}
Being full definitions in the header, each of these functions gets implemented in each object file for every .cpp
file that they get included in. That's why the linker complains about the function in one object file being already defined in another object file. This is a violation of C++'s "one definition rule".
The inline
keyword is used to explicitly permit multiple definitions of a function (as long as they are identical).
As an alternative, you could remove the definition of the functions from the header file, leaving only a prototype for them there. Then put the definition in a single .cpp
file for the linker to find:
// in SapPositionClass.hpp:
SapArchive& operator <<(SapArchive& stream,const SapPositionClass& obj);
SapArchive& operator >>(SapArchive& stream,SapPositionClass& obj);
And:
// in SapPositionClass.cpp:
SapArchive& operator <<(SapArchive& stream,const SapPositionClass& obj)
{
stream << obj.mush_Id << obj.msz_title << obj.md_latitude << obj.md_longitude << obj.msh_altitudeMeter;
return stream;
}
SapArchive& operator >>(SapArchive& stream,SapPositionClass& obj)
{
stream >> obj.mush_Id >> obj.msz_title >> obj.md_latitude >> obj.md_longitude >> obj.msh_altitudeMeter;
return stream;
}
Upvotes: 4