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
问题: 当我编译这些类时,我得到以下警告
SapSafeLaneClass.obj:-1:警告:LNK4006:“类SapArchive&amp; __cdecl运算符&lt;&lt;(类 SapArchive&amp;,类SapPositionClass const&amp;)“ (?? 6 @ YAAAVSapArchive @ AAV3452 @ ABVSapPositionClass @ 012 @@ Z)已在SapMinefieldBreachClass.obj中定义; 忽略第二个定义
请帮助避免此警告......
答案 0 :(得分:4)
将inline
关键字添加到operator <<(SapArchive&,const SapPositionClass&)
中operator >>(SapArchive&,SapPositionClass&)
和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;
}
在标头中作为完整定义,每个目标文件中的每一个都会为它们包含的每个.cpp
文件实现。这就是为什么链接器在一个已定义的目标文件中抱怨该函数的原因。另一个目标文件。这违反了C ++的“一个定义规则”。
inline
关键字用于明确允许函数的多个定义(只要它们相同)。
作为替代方案,您可以从头文件中删除函数的定义,只留下它们的原型。然后将定义放在单个.cpp
文件中,以便链接器查找:
// in SapPositionClass.hpp:
SapArchive& operator <<(SapArchive& stream,const SapPositionClass& obj);
SapArchive& operator >>(SapArchive& stream,SapPositionClass& obj);
和
// 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;
}