3

Windows 7 cygwin 1.7.20 gcc 4.5.3

クラスの 1 つにメソッド enqueue(const PTR X, const void* operation) がありますが、それを呼び出そうとすると、別のメソッドが実際に呼び出され、enqueue(bool X)' 元のメソッドが次のように変更されると、 、enqueue(const PTR X) が正しく呼び出されます。この行動を誘発するために何をしたのかわかりません。コードはコンパイル可能です。

/****** SlipDef.h ******/

#ifndef SLIPDEF_H
#define SLIPDEF_H
# include <string>
# include "SlipPointer.h"
using namespace std;
namespace slip {
    typedef unsigned char   UCHAR;
    typedef signed   char   CHAR;
    typedef unsigned short  USHORT;
    typedef signed   short  SHORT;
    typedef unsigned int    UINT;
    typedef signed   int    INT;
    typedef unsigned long   ULONG;
    typedef signed   long   LONG;
    typedef float           FLOAT;
    typedef double          DOUBLE;
    typedef SlipPointer *   PTR;
    typedef SlipPointer *   STRING;
} // namespace slip
#endif  /* SLIPDEF_H */
/****** SlipHeader.h ******/

#ifndef _SLIPHEADER_H
#define _SLIPHEADER_H
# include <string>
# include "SlipDef.h"
namespace slip {

   class SlipHeader {
   public:
      SlipHeader&       enqueue(SlipHeader& X);
      SlipHeader&       enqueue(bool X);
      SlipHeader&       enqueue(UCHAR X);
      SlipHeader&       enqueue(CHAR X);
      SlipHeader&       enqueue(ULONG X);
      SlipHeader&       enqueue(LONG X);
      SlipHeader&       enqueue(DOUBLE X);
      SlipHeader&       enqueue(const PTR X, const void* operation);
      SlipHeader&       enqueue(const string& X, bool constFlag = false);
      SlipHeader&       enqueue(const string* X, bool constFlag = false);
    };
};
#endif  /* SLIPHEADER_H */

/****** SlipPointer.h ******/

#ifndef SLIPPOINTER_H
#define SLIPPOINTER_H
using namespace std;
namespace slip {

   class SlipPointer { 
   public:
   };
} // namespace slip
#endif  /* SLIPPOINTER_H */

/****** TheOtherHeader.h ******/

#ifndef _THEOTHERHEADER_H
#define _THEOTHERHEADER_H
# include <string>
# include "SlipDef.h"
namespace slip {

   class TheOtherHeader {
   public:
      TheOtherHeader&   enqueue(TheOtherHeader& X);
      TheOtherHeader&   enqueue(bool X);
      TheOtherHeader&   enqueue(UCHAR X);
      TheOtherHeader&   enqueue(CHAR X);
      TheOtherHeader&   enqueue(ULONG X);
      TheOtherHeader&   enqueue(LONG X);
      TheOtherHeader&   enqueue(DOUBLE X);
      TheOtherHeader&   enqueue(const PTR X);
      TheOtherHeader&   enqueue(const string& X, bool constFlag = false);
      TheOtherHeader&   enqueue(const string* X, bool constFlag = false);
    };
};
#endif  /* _THEOTHERHEADER_H */

/****** main.cpp ******/

# include "SlipHeader.h"
#include "TheOtherHeader.h"
# include <string>
# include <iostream>
using namespace std;
using namespace slip;

int main(int argc, char** argv) {
   SlipPointer*    ptr    = new SlipPointer();
   SlipHeader*     header = new SlipHeader();
   TheOtherHeader* theOtherHeader = new TheOtherHeader();
   header->enqueue(ptr);
   theOtherHeader->enqueue(ptr);
return 0;
}

/****** SlipHeader.cpp ******/

# include <string>
# include <iostream>
# include "SlipDef.h"
# include "SlipHeader.h"
namespace slip {
   static void* ptrOP;
   SlipHeader& SlipHeader::enqueue(SlipHeader& X) { cout << "enqueue(SlipHeader& X) wrong answer" << endl; return *new SlipHeader();}
   SlipHeader& SlipHeader::enqueue(bool X)      { cout << "enqueue(bool X) wrong answer" << endl;      return *new SlipHeader();}
   SlipHeader& SlipHeader::enqueue(UCHAR X)     { cout << "enqueue(UCHAR X) wrong answer" << endl;     return *new SlipHeader();}
   SlipHeader& SlipHeader::enqueue(CHAR X)      { cout << "enqueue(CHAR X) wrong answer" << endl;      return *new SlipHeader();}
   SlipHeader& SlipHeader::enqueue(ULONG X)     { cout << "enqueue(ULONG X) wrong answer" << endl;     return *new SlipHeader();}
   SlipHeader& SlipHeader::enqueue(LONG X)      { cout << "enqueue(LONG X) wrong answer" << endl;      return *new SlipHeader();}
   SlipHeader& SlipHeader::enqueue(DOUBLE X)    { cout << "enqueue(DOUBLE X) wrong answer" << endl;    return *new SlipHeader();}
   SlipHeader& SlipHeader::enqueue(const PTR X, const void* operation = ptrOP) {
      cout << "enqueue(PTR X) right answer" << endl; return *new SlipHeader();
   };
   SlipHeader& SlipHeader::enqueue(const string& X, bool constFlag) { cout << "enqueue(string& X) wrong answer" << endl; return *new SlipHeader();}
   SlipHeader& SlipHeader::enqueue(const string* X, bool constFlag) { cout << "enqueue(string* X) wrong answer" << endl; return *new SlipHeader();}
};
/****** TheOtherHeader.cpp ******/

# include <string>
# include <iostream>
# include "SlipDef.h"
# include "TheOtherHeader.h"
namespace slip {
   static void* ptrOP;
   TheOtherHeader& TheOtherHeader::enqueue(TheOtherHeader& X) { cout << "enqueue(TheOtherHeader& X) wrong answer" << endl; return *new TheOtherHeader();}
   TheOtherHeader& TheOtherHeader::enqueue(bool X)      { cout << "enqueue(bool X) wrong answer" << endl;      return *new TheOtherHeader();}
   TheOtherHeader& TheOtherHeader::enqueue(UCHAR X)     { cout << "enqueue(UCHAR X) wrong answer" << endl;     return *new TheOtherHeader();}
   TheOtherHeader& TheOtherHeader::enqueue(CHAR X)      { cout << "enqueue(CHAR X) wrong answer" << endl;      return *new TheOtherHeader();}
   TheOtherHeader& TheOtherHeader::enqueue(ULONG X)     { cout << "enqueue(ULONG X) wrong answer" << endl;     return *new TheOtherHeader();}
   TheOtherHeader& TheOtherHeader::enqueue(LONG X)      { cout << "enqueue(LONG X) wrong answer" << endl;      return *new TheOtherHeader();}
   TheOtherHeader& TheOtherHeader::enqueue(DOUBLE X)    { cout << "enqueue(DOUBLE X) wrong answer" << endl;    return *new TheOtherHeader();}
   TheOtherHeader& TheOtherHeader::enqueue(const PTR X) {
      cout << "enqueue(PTR X) right answer" << endl; return *new TheOtherHeader();
   };
   TheOtherHeader& TheOtherHeader::enqueue(const string& X, bool constFlag) { cout << "enqueue(string& X) wrong answer" << endl; return *new TheOtherHeader();}
   TheOtherHeader& TheOtherHeader::enqueue(const string* X, bool constFlag) { cout << "enqueue(string* X) wrong answer" << endl; return *new TheOtherHeader();}
};
4

2 に答える 2

1

へのデフォルトの引数がありますconst void* operation。ただし、ヘッダーではなく実装でこれらのデフォルト引数を設定します。逆にする必要があります。

// header
void f(int x=5);

// implementation
void f(int x) { }

この理由は単純です。header->enqueue(ptr)メイン コードを呼び出すと、コンパイラはヘッダーによって提供される情報しか認識しません。ヘッダーにデフォルト引数が含まれていない場合、コンパイラはその時点でデフォルト引数の存在を認識しません。

于 2013-06-24T20:41:54.563 に答える
0

ヘッダーファイルがこれを定義しているため:

SlipHeader&       enqueue(const PTR X, const void* operation);

そして、あなたはそれを次のように呼びます:

header->enqueue(ptr);

コンパイラは、宣言を関数呼び出しの有効な一致と見なさず (1 つの引数のみを渡し、2 番目の既定の引数を宣言しません)、代わりに単一の引数で呼び出すことができるものの 1 つを選択します。標準をもう少し掘り下げる必要があるものを選択する理由。bool

関数の実際の定義で 2 番目の引数にデフォルト引数を指定するという事実は、コンパイラが をコンパイルするときにコンパイラから見えないため、main()考慮されません。デフォルトの引数をヘッダーに移動する必要があります (実際、警告がオンになっている場合は、現在の配置方法に基づいて警告が表示されるはずです)。

編集: aschepler が以下で指摘しているように、boolバージョンが呼び出される理由は、[const] void *.

于 2013-06-24T20:43:33.037 に答える