重载的非成员运算符== undefined?

时间:2013-01-10 13:44:32

标签: c++ operator-overloading

g ++ 4.5.3(cygwin)

我在定义重载的非成员运算符==时遇到了问题。编译器输出错误消息

  

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

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

另一个问题是当从Slip.cpp中删除'#include SlipOp.h''时,Slip.cpp中未定义SlipDatum。我查看了SlipDatum.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

1 个答案:

答案 0 :(得分:3)

在slip.cpp中,您在全局范围内定义operator ==,即您错过了命名空间:

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