0

g++ 4.5.3 (cygwin)

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

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

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

另一个问题是,当从 Slip.cpp 中删除 '#include SlipOp.h"' 时,SlipDatum 在 Slip.cpp 中未定义。我查看了 SlipDatum.h 并且不需要 SlipOp.h。我查看了 SlipDatum .cpp 和 SlipOp.h 是需要和包含的,SlipOp.h 在 Slip.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;
}

滑倒.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 */

滑动.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; };

滑动定义

#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 */

滑动基准.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

滑动基准面.cpp

# include "SlipDatum.h"
# include "SlipOP.h"
# include "SlipCellBase.h"

bool SlipDatum::operator==(const bool X)
    { return ((SlipOp*)*getOperator())->equal(*this, X); }

滑点

#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 */

滑动布尔.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 */

滑动布尔.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
4

1 回答 1

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                                          
  }; 
};
于 2013-01-10T13:48:55.157 回答