微软VC各版本BUG: error C2660: 'new' : function does not take 3 parameters
2008-05-18 15:56
转自:
点击打开链接
今天在用GDI+写程序时,有
HatchBrush * brushDotDiamond =
new
HatchBrush
(HatchStyle25Percent,color);
用VC6 SP6或VS2005编译错误为error C2660: 'new' : function does not take 3 parameters
这是VC的一个BUG,微软至今还没有解除。
解决办法如下:
法一:在该CPP文件开头部分注释掉#define new DEBUG_NEW
#ifdef
_DEBUG
//#define new DEBUG_NEW
#undef
THIS_FILE
static
char
THIS_FILE
[] = __FILE__;
#endif
建议法二:在GdiplusBase.h文件中class GdiplusBase中添加如下代码
//
void * (operator new)(size_t nSize, LPCSTR lpszFileName, int nLine) { return DllExports::GdipAlloc(nSize); } void operator delete(void* p, LPCSTR lpszFileName, int nLine) { DllExports::GdipFree(p); } //
下面是转载文章,作者:billdavid
不让用盗版,遂准备逐一将各软件要么换成开源的,要么就自己写,看了看,就数Acdsee最简单了(有些高级功能根本用不着),行,从这个入手吧。
需求分析:基本的图片查看功能,图片格式转换功能,基本的图形变换功能。 技术可行性分析:MS提供的GDI+已经提供了比较专业的图形显示、格式转换功能,而且简单易用。 .... OK,就绪,开始干吧。 但是在程序编写的过程中,有条错误信息让我很不解。程序中有如下语句: bmPhoto = new Bitmap( THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, PixelFormat24bppRGB ); 每次DEBUG编译的时候总是报告如下的错误: error C2660: 'new' : function does not take 3 parameters 开始以为是Bitmap的构造函数的问题,但是查了一下,Bitmap明明有个构造函数: Bitmap(IN INT width, IN INT height, IN PixelFormat format = PixelFormat32bppARGB); 那会是什么问题呢?上网讨论了一下,最终将问题锁定在MFC程序中的这样一个宏定义上: #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif 这几行从来都不会引起我们注意的代码有什么问题呢?为什么会使得我们的代码报告如上所述的编译错误呢? 让我们来看看DEBUG_NEW的定义(在afx.h中): #if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT) // Memory tracking allocation void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine); #define DEBUG_NEW new(THIS_FILE, __LINE__) #if _MSC_VER >= 1200 void AFX_CDECL operator delete(void* p, LPCSTR lpszFileName, int nLine); #endif 看到这里你可能会想,new被define成了DEBUG_NEW,而后者又被define成了new(...),这不是成了个循环?非也。由于afx.h早于任何其它头文件被包含(stdafx.h包含afxwin.h,afxwin.h又包含了afx.h,而MFC要求我们在任何有效代码之前包含stdafx.h,当然,这不是必须的),所以DEBUG_NEW的定义早于后面的#define new DEBUG_NEW,也就是说这个define只对后面的代码有效,对前面已经include了的afx.h中的代码是无效的。 上面只是题外话,现在回到正题。 MFC重载operator new,是为了方便定位内存泄漏,重载后的operator new会记录下所分配的每块内存对应的__FILE__和__LINE__信息。一般来讲,标准的operator new的声明如下: void *__cdecl operator new(size_t); 即它只有一个参数,只接收一个size信息。我们的如下代码 int* pi = new int; // the same as int* pi = new int(); or int* pi = new int[1]; 等价于 int* tpi = (int*)operator new(sizeof(int)); // attention: this line cannot pass compilation if you have define DEBUG_NEW int* pi = tpi; 同理,定义DEBUG_NEW前,文章开头报错的这条语句: Bitmap* bmPhoto = new Bitmap( THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, PixelFormat24bppRGB ); 等价于 Bitmap* tbmPhoto = (Bitmap*)operator new(sizeof(Bitmap)); tbmPhoto->Bitmap( THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, PixelFormat24bppRGB ); // initialize variable Bitmap* bmPhoto = tbmPhoto; 但是现在,由于DEBUG_NEW使用的是被重载的operator new: void* AFX_CDECL operator new(size_t nSize, LPCSTR lpszFileName, int nLine); 上述代码等价于: Bitmap* tbmPhoto = (Bitmap*)operator new(sizeof(Bitmap), __FILE__, __LINE__); tbmPhoto->BitmapBitmap( THUMBNAIL_WIDTH, THUMBNAIL_HEIGHT, PixelFormat24bppRGB ); // initialize variable Bitmap* bmPhoto = tbmPhoto; 回过头来看gdiplus.h中的operator new的声明(在GdiplusBase.h中): class GdiplusBase { public: void (operator delete)(void* in_pVoid) { DllExports::GdipFree(in_pVoid); } void* (operator new)(size_t in_size) { return DllExports::GdipAlloc(in_size); } void (operator delete[])(void* in_pVoid) { DllExports::GdipFree(in_pVoid); } void* (operator new[])(size_t in_size) { return DllExports::GdipAlloc(in_size); } }; 它重载了operator new,并且没有提供一个可以容纳3个参数的operator new,同时基于这样一个事实: 不同命名域(指全局命名空间与有名命名空间之间,父类与子类,全局与类内部)内进行重载时,下一级的命名空间会覆盖掉上一级的定义,除非显示调用上一级的定义。 因此,全局的重新定义的operator new并不能用于Bitmap类。也正因为这一原因,编译器会报告: Bitmap* tbmPhoto = (Bitmap*)Bitmap::operator new(sizeof(Bitmap), __FILE__, __LINE__); error C2660: 'new' : function does not take 3 parameters 知道了这一点,要修正这一问题,只需给class GdiplusBase多重载几个operator new即可。修正后的class GdiplusBase如下: #ifdef _DEBUG namespace Gdiplus { namespace DllExports { #include <GdiplusMem.h> }; |