【发布时间】:2013-01-10 13:44:31
【问题描述】:
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。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;
}
滑动.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; };
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
【问题讨论】:
-
tl;dr 但您几乎肯定想从
Slip.cpp中operator==的定义中删除inline。除此之外可能还有其他问题。哦,是的,如果您要定义在头文件中声明的相同函数,您可能希望将定义放在slip命名空间中。