3

Windows 7 cygwin 1.7.20 gcc 4.5.3

我的一个类中有一个方法,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);

编译器不会将声明视为函数调用的有效匹配项(您只传递一个参数,并且不为第二个声明默认参数),而是选择一个可以用单个参数调用的参数。为什么它选择bool一个需要更多地挖掘标准。

您在函数的实际定义中为第二个参数提供默认参数这一事实在编译器编译时是不可见的main(),因此不予考虑。您应该将默认参数移动到标题中(事实上,如果您有警告,您可能应该根据您现在安排它的方式收到警告)。

编辑:正如 aschepler 在下面指出的,bool版本被调用的原因是它是唯一允许的[const] void *.

于 2013-06-24T20:43:33.037 回答