g ++ 4.5.3(cygwin)
オーバーロードされた非メンバー演算子==の定義に問題があります。コンパイラはエラーメッセージを出力します
main.cpp:11: `slip :: operator ==(bool、slip :: SlimDatum const&)への未定義の参照
何が間違っているのか理解できません。すべての定義が表示され、すべての関数プロトタイプとコードが正しいように思えます。「(SlipDatum&)Y ==(bool)X」のようにオーバーロードをメンバー関数として使用する場合、問題はありません。非メンバー関数として、私は未定義の参照を取得し続けます。
もう1つの問題は、「#include SlipOp.h」がSlip.cppから削除されると、SlipDatumがSlip.cppで未定義になることです。SlipDatum.hを確認しましたが、SlipOp.hは必要ありません。SlipDatumを確認しました。 .cppとSlipOp.hが必要であり、含まれています。SlipOp.hは不要であるか、Slip.cppで参照されていません。それでは、なぜコンパイラーはそれが必要であると考えるのでしょうか。
使用されるサンプルコードは次のとおりです。
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