1
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);
};

#万一

问题:当我编译这些类时,我收到以下警告


SapSafeLaneClass.obj:-1: 警告: LNK4006: "class SapArchive & __cdecl operator<<(class SapArchive &,class SapPositionClass const &)" (??6@YAAAVSapArchive@AAV3452@ABVSapPositionClass@012@@Z) 已在 SapMinefieldBreachClass 中定义.obj; 第二个定义被忽略

请帮助避免此警告....

4

1 回答 1

4

inline关键字添加到operator <<(SapArchive&,const SapPositionClass&)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;
}

作为头文件中的完整定义,这些函数中的每一个都在每个包含它们的文件的每个目标文件中实现.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;
}
于 2013-07-12T08:42:44.297 回答