警告lnk4006在Qt

时间:2013-07-12 06:22:43

标签: c++ qt linker-errors

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中定义;    忽略第二个定义

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

1 个答案:

答案 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;
}