⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gdi+编程中的一条错误信息及其原因分析.htm

📁 GDI编程的参考资料
💻 HTM
📖 第 1 页 / 共 5 页
字号:
            color=#000099><BR>#ifdef&nbsp;_DEBUG<BR>#define&nbsp;new&nbsp;DEBUG_NEW<BR>#undef&nbsp;THIS_FILE<BR></FONT><FONT 
            color=#990000>static</FONT><FONT 
            color=#ff6633>&nbsp;char</FONT>&nbsp;THIS_FILE<B><FONT 
            color=#663300>[]&nbsp;=</FONT></B>&nbsp;__FILE__<B><FONT 
            color=#663300>;</FONT></B><FONT 
            color=#000099><BR>#endif<BR></FONT>这几行从来都不会引起我们注意的代码有什么问题呢<B><FONT 
            color=#663300>?</FONT></B>为什么会使得我们的代码报告如上所述的编译错误呢<B><FONT 
            color=#663300>?</FONT></B><BR>让我们来看看DEBUG_NEW的定义(在afx<B><FONT 
            color=#663300>.</FONT></B>h中):<FONT 
            color=#000099><BR>#if&nbsp;defined(_DEBUG)&nbsp;&amp;&amp;&nbsp;!defined(_AFX_NO_DEBUG_CRT)<BR></FONT><I><FONT 
            color=#999999><BR>//&nbsp;Memory&nbsp;tracking&nbsp;allocation<BR></FONT></I><FONT 
            color=#ff6633>void</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;AFX_CDECL<FONT 
            color=#990000>&nbsp;operator&nbsp;new</FONT><B><FONT 
            color=#663300>(</FONT></B>size_t&nbsp;nSize<B><FONT 
            color=#663300>,</FONT></B>&nbsp;LPCSTR&nbsp;lpszFileName<B><FONT 
            color=#663300>,</FONT></B><FONT 
            color=#ff6633>&nbsp;int</FONT>&nbsp;nLine<B><FONT 
            color=#663300>);</FONT></B><FONT 
            color=#000099><BR>#define&nbsp;DEBUG_NEW&nbsp;new(THIS_FILE,&nbsp;__LINE__)<BR>#if&nbsp;_MSC_VER&nbsp;&gt;=&nbsp;1200<BR></FONT><FONT 
            color=#ff6633>void</FONT>&nbsp;AFX_CDECL<FONT 
            color=#990000>&nbsp;operator&nbsp;delete</FONT><B><FONT 
            color=#663300>(</FONT></B><FONT color=#ff6633>void</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;p<B><FONT 
            color=#663300>,</FONT></B>&nbsp;LPCSTR&nbsp;lpszFileName<B><FONT 
            color=#663300>,</FONT></B><FONT 
            color=#ff6633>&nbsp;int</FONT>&nbsp;nLine<B><FONT 
            color=#663300>);</FONT></B><FONT 
            color=#000099><BR>#endif<BR></FONT>看到这里你可能会想,<FONT 
            color=#990000>new</FONT>被define成了DEBUG_NEW,而后者又被define成了<FONT 
            color=#990000>new</FONT><B><FONT 
            color=#663300>(...)</FONT></B>,这不是成了个循环<B><FONT 
            color=#663300>?</FONT></B>非也。由于afx<B><FONT 
            color=#663300>.</FONT></B>h早于任何其它头文件被包含<B><FONT 
            color=#663300>(</FONT></B>stdafx<B><FONT 
            color=#663300>.</FONT></B>h包含afxwin<B><FONT 
            color=#663300>.</FONT></B>h,afxwin<B><FONT 
            color=#663300>.</FONT></B>h又包含了afx<B><FONT 
            color=#663300>.</FONT></B>h,而MFC要求我们在任何有效代码之前包含stdafx<B><FONT 
            color=#663300>.</FONT></B>h,当然,这不是必须的<B><FONT 
            color=#663300>)</FONT></B>,所以DEBUG_NEW的定义早于后面的#define<FONT 
            color=#990000>&nbsp;new</FONT>&nbsp;DEBUG_NEW,也就是说这个define只对后面的代码有效,对前面已经include了的afx<B><FONT 
            color=#663300>.</FONT></B>h中的代码是无效的。<BR><BR>上面只是题外话,现在回到正题。<BR>MFC重载<FONT 
            color=#990000>operator&nbsp;new</FONT>,是为了方便定位内存泄漏,重载后的<FONT 
            color=#990000>operator&nbsp;new</FONT>会记录下所分配的每块内存对应的__FILE__和__LINE__信息。一般来讲,标准的<FONT 
            color=#990000>operator&nbsp;new</FONT>的声明如下:<FONT 
            color=#ff6633><BR>void</FONT><B><FONT 
            color=#663300>&nbsp;*</FONT></B>__cdecl<FONT 
            color=#990000>&nbsp;operator&nbsp;new</FONT><B><FONT 
            color=#663300>(</FONT></B>size_t<B><FONT 
            color=#663300>);</FONT></B><BR>即它只有一个参数,只接收一个size信息。我们的如下代码<FONT 
            color=#ff6633><BR>int</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;pi<B><FONT 
            color=#663300>&nbsp;=</FONT></B><FONT 
            color=#990000>&nbsp;new</FONT><FONT 
            color=#ff6633>&nbsp;int</FONT><B><FONT 
            color=#663300>;</FONT></B><I><FONT 
            color=#999999>&nbsp;//&nbsp;the&nbsp;same&nbsp;as&nbsp;int*&nbsp;pi&nbsp;=&nbsp;new&nbsp;int();&nbsp;or&nbsp;int*&nbsp;pi&nbsp;=&nbsp;new&nbsp;int[1];<BR></FONT></I>等价于<FONT 
            color=#ff6633><BR>int</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;tpi<B><FONT 
            color=#663300>&nbsp;=&nbsp;(</FONT></B><FONT 
            color=#ff6633>int</FONT><B><FONT color=#663300>*)</FONT></B><FONT 
            color=#990000>operator&nbsp;new</FONT><B><FONT 
            color=#663300>(</FONT></B><FONT color=#990000>sizeof</FONT><B><FONT 
            color=#663300>(</FONT></B><FONT color=#ff6633>int</FONT><B><FONT 
            color=#663300>));</FONT></B><I><FONT 
            color=#999999>&nbsp;//&nbsp;attention:&nbsp;this&nbsp;line&nbsp;cannot&nbsp;pass&nbsp;compilation&nbsp;if&nbsp;you&nbsp;have&nbsp;define&nbsp;DEBUG_NEW<BR></FONT></I><FONT 
            color=#ff6633>int</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;pi<B><FONT 
            color=#663300>&nbsp;=</FONT></B>&nbsp;tpi<B><FONT 
            color=#663300>;</FONT></B><BR>同理,定义DEBUG_NEW前,文章开头报错的这条语句:<BR>Bitmap<B><FONT 
            color=#663300>*</FONT></B>&nbsp;bmPhoto<B><FONT 
            color=#663300>&nbsp;=</FONT></B><FONT 
            color=#990000>&nbsp;new</FONT>&nbsp;Bitmap<B><FONT 
            color=#663300>(</FONT></B>&nbsp;THUMBNAIL_WIDTH<B><FONT 
            color=#663300>,</FONT></B>&nbsp;THUMBNAIL_HEIGHT<B><FONT 
            color=#663300>,</FONT></B>&nbsp;PixelFormat24bppRGB<B><FONT 
            color=#663300>&nbsp;);</FONT></B><BR>等价于<BR>Bitmap<B><FONT 
            color=#663300>*</FONT></B>&nbsp;tbmPhoto<B><FONT 
            color=#663300>&nbsp;=&nbsp;(</FONT></B>Bitmap<B><FONT 
            color=#663300>*)</FONT></B><FONT 
            color=#990000>operator&nbsp;new</FONT><B><FONT 
            color=#663300>(</FONT></B><FONT color=#990000>sizeof</FONT><B><FONT 
            color=#663300>(</FONT></B>Bitmap<B><FONT 
            color=#663300>));</FONT></B><BR>tbmPhoto<B><FONT 
            color=#663300>-&gt;</FONT></B>Bitmap<B><FONT 
            color=#663300>(</FONT></B>&nbsp;THUMBNAIL_WIDTH<B><FONT 
            color=#663300>,</FONT></B>&nbsp;THUMBNAIL_HEIGHT<B><FONT 
            color=#663300>,</FONT></B>&nbsp;PixelFormat24bppRGB<B><FONT 
            color=#663300>&nbsp;);</FONT></B><I><FONT 
            color=#999999>&nbsp;//&nbsp;initialize&nbsp;variable<BR></FONT></I>Bitmap<B><FONT 
            color=#663300>*</FONT></B>&nbsp;bmPhoto<B><FONT 
            color=#663300>&nbsp;=</FONT></B>&nbsp;tbmPhoto<B><FONT 
            color=#663300>;</FONT></B><BR>但是现在,由于DEBUG_NEW使用的是被重载的<FONT 
            color=#990000>operator&nbsp;new</FONT>:<FONT 
            color=#ff6633><BR>void</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;AFX_CDECL<FONT 
            color=#990000>&nbsp;operator&nbsp;new</FONT><B><FONT 
            color=#663300>(</FONT></B>size_t&nbsp;nSize<B><FONT 
            color=#663300>,</FONT></B>&nbsp;LPCSTR&nbsp;lpszFileName<B><FONT 
            color=#663300>,</FONT></B><FONT 
            color=#ff6633>&nbsp;int</FONT>&nbsp;nLine<B><FONT 
            color=#663300>);</FONT></B><BR>上述代码等价于:<BR>Bitmap<B><FONT 
            color=#663300>*</FONT></B>&nbsp;tbmPhoto<B><FONT 
            color=#663300>&nbsp;=&nbsp;(</FONT></B>Bitmap<B><FONT 
            color=#663300>*)</FONT></B><FONT 
            color=#990000>operator&nbsp;new</FONT><B><FONT 
            color=#663300>(</FONT></B><FONT color=#990000>sizeof</FONT><B><FONT 
            color=#663300>(</FONT></B>Bitmap<B><FONT 
            color=#663300>),</FONT></B>&nbsp;__FILE__<B><FONT 
            color=#663300>,</FONT></B>&nbsp;__LINE__<B><FONT 
            color=#663300>);</FONT></B><BR>tbmPhoto<B><FONT 
            color=#663300>-&gt;</FONT></B>BitmapBitmap<B><FONT 
            color=#663300>(</FONT></B>&nbsp;THUMBNAIL_WIDTH<B><FONT 
            color=#663300>,</FONT></B>&nbsp;THUMBNAIL_HEIGHT<B><FONT 
            color=#663300>,</FONT></B>&nbsp;PixelFormat24bppRGB<B><FONT 
            color=#663300>&nbsp;);</FONT></B><I><FONT 
            color=#999999>&nbsp;//&nbsp;initialize&nbsp;variable<BR></FONT></I>Bitmap<B><FONT 
            color=#663300>*</FONT></B>&nbsp;bmPhoto<B><FONT 
            color=#663300>&nbsp;=</FONT></B>&nbsp;tbmPhoto<B><FONT 
            color=#663300>;</FONT></B><BR>回过头来看gdiplus<B><FONT 
            color=#663300>.</FONT></B>h中的<FONT 
            color=#990000>operator&nbsp;new</FONT>的声明(在GdiplusBase<B><FONT 
            color=#663300>.</FONT></B>h中):<FONT 
            color=#990000><BR>class</FONT>&nbsp;GdiplusBase<B><FONT 
            color=#663300><BR>{</FONT></B><FONT 
            color=#990000><BR>public</FONT><B><FONT 
            color=#663300>:</FONT></B><FONT 
            color=#ff6633><BR>&nbsp;&nbsp;&nbsp;&nbsp;void</FONT><B><FONT 
            color=#663300>&nbsp;(</FONT></B><FONT 
            color=#990000>operator&nbsp;delete</FONT><B><FONT 
            color=#663300>)(</FONT></B><FONT color=#ff6633>void</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;in_pVoid<B><FONT 
            color=#663300>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></B><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DllExports<B><FONT 
            color=#663300>::</FONT></B>GdipFree<B><FONT 
            color=#663300>(</FONT></B>in_pVoid<B><FONT 
            color=#663300>);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></B><FONT 
            color=#ff6633><BR>&nbsp;&nbsp;&nbsp;&nbsp;void</FONT><B><FONT 
            color=#663300>*&nbsp;(</FONT></B><FONT 
            color=#990000>operator&nbsp;new</FONT><B><FONT 
            color=#663300>)(</FONT></B>size_t&nbsp;in_size<B><FONT 
            color=#663300>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></B><FONT 
            color=#ff0000><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return</FONT>&nbsp;DllExports<B><FONT 
            color=#663300>::</FONT></B>GdipAlloc<B><FONT 
            color=#663300>(</FONT></B>in_size<B><FONT 
            color=#663300>);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></B><FONT 
            color=#ff6633><BR>&nbsp;&nbsp;&nbsp;&nbsp;void</FONT><B><FONT 
            color=#663300>&nbsp;(</FONT></B><FONT 
            color=#990000>operator&nbsp;delete</FONT><B><FONT 
            color=#663300>[])(</FONT></B><FONT color=#ff6633>void</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;in_pVoid<B><FONT 
            color=#663300>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></B><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;DllExports<B><FONT 
            color=#663300>::</FONT></B>GdipFree<B><FONT 
            color=#663300>(</FONT></B>in_pVoid<B><FONT 
            color=#663300>);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}</FONT></B><FONT 
            color=#ff6633><BR>&nbsp;&nbsp;&nbsp;&nbsp;void</FONT><B><FONT 
            color=#663300>*&nbsp;(</FONT></B><FONT 
            color=#990000>operator&nbsp;new</FONT><B><FONT 
            color=#663300>[])(</FONT></B>size_t&nbsp;in_size<B><FONT 
            color=#663300>)<BR>&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></B><FONT 
            color=#ff0000><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return</FONT>&nbsp;DllExports<B><FONT 
            color=#663300>::</FONT></B>GdipAlloc<B><FONT 
            color=#663300>(</FONT></B>in_size<B><FONT 
            color=#663300>);<BR>&nbsp;&nbsp;&nbsp;&nbsp;}<BR>};</FONT></B><BR>它重载了<FONT 
            color=#990000>operator&nbsp;new</FONT>,并且没有提供一个可以容纳<FONT 
            color=#999900>3</FONT>个参数的<FONT 
            color=#990000>operator&nbsp;new</FONT>,同时基于这样一个事实:<BR>不同命名域(指全局命名空间与有名命名空间之间,父类与子类,全局与类内部)内进行重载时,下一级的命名空间会覆盖掉上一级的定义,除非显示调用上一级的定义。<BR>因此,全局的重新定义的<FONT 
            color=#990000>operator&nbsp;new</FONT>并不能用于Bitmap类。也正因为这一原因,编译器会报告:<BR>Bitmap<B><FONT 
            color=#663300>*</FONT></B>&nbsp;tbmPhoto<B><FONT 
            color=#663300>&nbsp;=&nbsp;(</FONT></B>Bitmap<B><FONT 
            color=#663300>*)</FONT></B>Bitmap<B><FONT 
            color=#663300>::</FONT></B><FONT 
            color=#990000>operator&nbsp;new</FONT><B><FONT 
            color=#663300>(</FONT></B><FONT color=#990000>sizeof</FONT><B><FONT 
            color=#663300>(</FONT></B>Bitmap<B><FONT 
            color=#663300>),</FONT></B>&nbsp;__FILE__<B><FONT 
            color=#663300>,</FONT></B>&nbsp;__LINE__<B><FONT 
            color=#663300>);</FONT></B><BR>error&nbsp;C2660<B><FONT 
            color=#663300>:</FONT></B><FONT 
            color=#009900>&nbsp;'new'</FONT><B><FONT 
            color=#663300>&nbsp;:</FONT></B>&nbsp;function&nbsp;does<FONT 
            color=#990000>&nbsp;not</FONT>&nbsp;take<FONT 
            color=#999900>&nbsp;3</FONT>&nbsp;parameters<BR>知道了这一点,要修正这一问题,只需给<FONT 
            color=#990000>class</FONT>&nbsp;GdiplusBase多重载几个<FONT 
            color=#990000>operator&nbsp;new</FONT>即可。修正后的<FONT 
            color=#990000>class</FONT>&nbsp;GdiplusBase如下:<FONT 
            color=#000099><BR>#ifdef&nbsp;_DEBUG<BR></FONT><FONT 
            color=#990000><BR>namespace</FONT>&nbsp;Gdiplus<B><FONT 
            color=#663300><BR>{</FONT></B><FONT 
            color=#990000><BR>&nbsp;&nbsp;&nbsp;&nbsp;namespace</FONT>&nbsp;DllExports<B><FONT 
            color=#663300><BR>&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></B><FONT 
            color=#000099><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;#include&nbsp;&lt;GdiplusMem.h&gt;<BR></FONT><B><FONT 
            color=#663300>&nbsp;&nbsp;&nbsp;&nbsp;};</FONT></B><FONT 
            color=#000099><BR><BR>&nbsp;&nbsp;&nbsp;&nbsp;#ifndef&nbsp;_GDIPLUSBASE_H<BR>&nbsp;&nbsp;&nbsp;&nbsp;#define&nbsp;_GDIPLUSBASE_H<BR></FONT><FONT 
            color=#990000>&nbsp;&nbsp;&nbsp;&nbsp;class</FONT>&nbsp;GdiplusBase<B><FONT 
            color=#663300><BR>&nbsp;&nbsp;&nbsp;&nbsp;{</FONT></B><FONT 
            color=#990000><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;public</FONT><B><FONT 
            color=#663300>:</FONT></B><FONT 
            color=#ff6633><BR>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;void</FONT><B><FONT 
            color=#663300>&nbsp;(</FONT></B><FONT 
            color=#990000>operator&nbsp;delete</FONT><B><FONT 
            color=#663300>)(</FONT></B><FONT color=#ff6633>void</FONT><B><FONT 
            color=#663300>*</FONT></B>&nbsp;in_pVoid<B><FONT 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -