0

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
4

1 に答える 1

3

slip.cpp では、 operator== をグローバル スコープで定義します。つまり、名前空間を見逃しています。

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

operator==(SlipDatum&, bool)PS: const 参照によって SlipDatum も取得する必要があるため、const_cast は必要ありません。つまり、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 に答える