重载非成员操作符==未定义

Overloaded non-member operator== undefined?

本文关键字:未定义 操作符 成员 重载      更新时间:2023-10-16

g++ 4.5.3 (cygwin)

我在定义重载非成员操作符==时遇到麻烦。编译器输出错误消息

main.cpp:11:未定义引用' slip::operator==(bool, slip::SlipDatum const&)

我不知道我做错了什么。在我看来,所有的定义都是可见的,所有的函数原型和代码都是正确的。当重载被用作成员函数时,如(SlipDatum&)Y == (bool)X",没有问题。作为一个非成员函数,我总是得到一个未定义的引用。

另一个问题是,当'#include SlipOp.h"'从Slip.cpp中删除时,SlipDatum在Slip.cpp中未定义。我看过slidatum .h和SlipOp.h是不需要的。我看了看SlipDatum.cpp和SlipOp.h是需要和包含的。在Slip.cpp中不需要或引用SlipOp.h,那么为什么编译器认为需要它呢?

使用的示例代码如下:

main.cpp

# include <cstdlib>
# include "Slip.h"
# include <iostream>
using namespace std;
using namespace slip;
int main(int argc, char** argv) {
   SlipDatum Y;
   bool X = true;
   if (X == Y) cout << "here" << endl;
   return 0;
}

Slip.h

#ifndef SLIP_H
#define SLIP_H
# include "SlipDatum.h"
namespace slip {
   bool      operator==(const bool   X, const SlipDatum& Y);  // Y == X
}; // namespace slip
#endif  /* SLIP_H */

Slip.cpp

# include "Slip.h"
# include "SlipCellBase.h"
# include "SlipOP.h"
# include "SlipDatum.h"
inline  bool operator==(const bool X, const SlipDatum& Y) 
     { return const_cast<SlipDatum&>(Y) == X; };

SlipDef.h

#ifndef SLIPDEF_H
#define SLIPDEF_H
# include <string>
using namespace std;
namespace slip {
#ifdef UCHAR
   # undef UCHAR
#endif
#ifdef ULONG
   # undef ULONG
#endif
#ifdef DOUBLE
   # undef DOUBLE
#endif
#ifdef PTR
   # undef PTR
#endif
   typedef unsigned char   UCHAR;               //  8-bits
   typedef unsigned long   ULONG;               // 32-bits
   typedef double          DOUBLE;              // 64-bits
   typedef void *          PTR;                 // pointer
   typedef string *        STRING;              // C String
   union Data {                                 // Slip data contents
       bool      Bool;                          // compiler defined
       char      Chr;                           //  8-bits
       UCHAR     UChr;                          //  8-bits
       long      Long;                          // 32-bits
       ULONG     ULong;                         // 32-bits
       double    Double;                        // 64-bits
       PTR       Ptr;                           // 
       STRING    String;                        // pointer to a string
   }; // union Data
} // namespace slip
#endif  /* SLIPDEF_H */

SlipCellBase.h

#ifndef _SLIPCELLBASE_H
#define _SLIPCELLBASE_H
# include "SlipDef.h"
using namespace std;
namespace slip {
  class SlipCellBase {
     friend class SlipOp;
  private:
      void*         operation;   //! Operations cell can perform
      SlipCellBase* leftLink;    //! Pointer to preceding cell
      SlipCellBase* rightLink;   //! Pointer to following cell
      Data          datum;       //! SLIP cell data field
 protected:
      void** getOperator() const 
           { return &const_cast<SlipCellBase*>(this)->operation; }
      static void** getOperator(SlipCellBase* X) 
           { return   &(X->operation);   }
  }; // class SlipCellBase
}; // namespace slip
#endif  /* SLILPCELLBASE_H */

SlipDatum.h

#ifndef SLIP_DATUM_H
#define SLIP_DATUM_H
# include "SlipCellBase.h"
namespace slip {
  class SlipDatum : public SlipCellBase {
  public:
     bool       operator==(const bool X);  // Y == X
  }; // SlipDatum
}; // namespace slip
#endif

SlipDatum.cpp

# include "SlipDatum.h"
# include "SlipOP.h"
# include "SlipCellBase.h"
bool SlipDatum::operator==(const bool X)
    { return ((SlipOp*)*getOperator())->equal(*this, X); }

SlipOp.h

#ifndef _SLIPOP_H
#define _SLIPOP_H
# include "SlipDatum.h"
using namespace slip;
namespace slip {
  class SlipOp {
  public:
     virtual bool equal(SlipDatum& Y, const bool X)  = 0;
  }; // class SlipOp
}; // namespace slip
#endif  /* _SLIPOP_H */

SlipBool.h

#ifndef _SLIPboolOP_H
#define _SLIPboolOP_H
# include "SlipOp.h"
namespace slip {
  class SlipBoolOp : public SlipOp {
  public:
     virtual bool equal(SlipDatum& Y, const bool   X);
  }; // class SlipBoolOp
}; // namespace slip
#endif  /* SLIPboolOP_H */

SlipBool.cpp

# include "SlipBoolOp.h"
# include "SlipDatum.h"
using namespace slip;
namespace slip {
  bool SlipBoolOp::equal (SlipDatum& Y, const bool X) {
    return false;
  }; // bool SlipBoolOp::equal (SlipDatum& Y, const SlipDatum& X) 
}; // namespace slip

在slip.cpp中,您在全局范围内定义了操作符==,即您错过了名称空间:

namespace slip {
  bool operator==(bool X, const SlipDatum& Y) 
  { return const_cast<SlipDatum&>(Y) == X; };
}

PS: const_cast不应该是必需的,因为operator==(SlipDatum&, bool)也应该通过const引用获取SlipDatum。例如,在slipdatum.h/cpp:

namespace slip {
  class SlipDatum : public SlipCellBase {
  public:
     bool       operator==(bool X) const; // <--! *this is left constant                                          
  }; 
};