📄 gdi+编程中的一条错误信息及其原因分析.htm
字号:
color=#663300>)<BR> {</FONT></B><BR> DllExports<B><FONT
color=#663300>::</FONT></B>GdipFree<B><FONT
color=#663300>(</FONT></B>in_pVoid<B><FONT
color=#663300>);<BR> }</FONT></B><FONT
color=#ff6633><BR><BR> void</FONT><B><FONT
color=#663300>* (</FONT></B><FONT
color=#990000>operator new</FONT><B><FONT
color=#663300>)(</FONT></B>size_t in_size<B><FONT
color=#663300>)<BR> {</FONT></B><FONT
color=#ff0000><BR> return</FONT> DllExports<B><FONT
color=#663300>::</FONT></B>GdipAlloc<B><FONT
color=#663300>(</FONT></B>in_size<B><FONT
color=#663300>);<BR> }</FONT></B><FONT
color=#ff6633><BR><BR> void</FONT><B><FONT
color=#663300> (</FONT></B><FONT
color=#990000>operator delete</FONT><B><FONT
color=#663300>[])(</FONT></B><FONT color=#ff6633>void</FONT><B><FONT
color=#663300>*</FONT></B> in_pVoid<B><FONT
color=#663300>)<BR> {</FONT></B><BR> DllExports<B><FONT
color=#663300>::</FONT></B>GdipFree<B><FONT
color=#663300>(</FONT></B>in_pVoid<B><FONT
color=#663300>);<BR> }</FONT></B><FONT
color=#ff6633><BR><BR> void</FONT><B><FONT
color=#663300>* (</FONT></B><FONT
color=#990000>operator new</FONT><B><FONT
color=#663300>[])(</FONT></B>size_t in_size<B><FONT
color=#663300>)<BR> {</FONT></B><FONT
color=#ff0000><BR> return</FONT> DllExports<B><FONT
color=#663300>::</FONT></B>GdipAlloc<B><FONT
color=#663300>(</FONT></B>in_size<B><FONT
color=#663300>);<BR> }</FONT></B><FONT
color=#ff6633><BR><BR> void</FONT><B><FONT
color=#663300> * (</FONT></B><FONT
color=#990000>operator new</FONT><B><FONT
color=#663300>)(</FONT></B>size_t nSize<B><FONT
color=#663300>,</FONT></B> LPCSTR lpszFileName<B><FONT
color=#663300>,</FONT></B><FONT
color=#ff6633> int</FONT> nLine<B><FONT
color=#663300>)<BR> {</FONT></B><FONT
color=#ff0000><BR> return</FONT> DllExports<B><FONT
color=#663300>::</FONT></B>GdipAlloc<B><FONT
color=#663300>(</FONT></B>nSize<B><FONT
color=#663300>);<BR> }</FONT></B><FONT
color=#ff6633><BR><BR> void</FONT><FONT
color=#990000> operator delete</FONT><B><FONT
color=#663300>(</FONT></B><FONT color=#ff6633>void</FONT><B><FONT
color=#663300>*</FONT></B> p<B><FONT
color=#663300>,</FONT></B> LPCSTR lpszFileName<B><FONT
color=#663300>,</FONT></B><FONT
color=#ff6633> int</FONT> nLine<B><FONT
color=#663300>)<BR> {</FONT></B><BR> DllExports<B><FONT
color=#663300>::</FONT></B>GdipFree<B><FONT
color=#663300>(</FONT></B>p<B><FONT
color=#663300>);<BR> }<BR><BR> };</FONT></B><FONT
color=#000099><BR> #endif // #ifndef _GDIPLUSBASE_H<BR></FONT><B><FONT
color=#663300>}</FONT></B><FONT
color=#000099><BR>#endif // #ifdef _DEBUG<BR></FONT>OK,问题已解决,其实这只是个重载<FONT
color=#990000>operator new</FONT>的问题,但这个问题由于DEBUG_NEW这个不起眼的宏,倒还真变得有点复杂。<BR><BR>最后总结一下,在进行<FONT
color=#990000>operator new</FONT>重载时应注意:<FONT
color=#996600><BR>1.</FONT><FONT
color=#990000>new operator</FONT>是不可以重载的,可以重载的是<FONT
color=#990000>operator new</FONT>。<FONT
color=#990000>new operator</FONT> 首先调用<FONT
color=#990000> operator new</FONT>,然后调用构造函数(如果有的话)。<FONT
color=#990000>new operator</FONT>的这个行为是不可以重载的,可以重载的仅仅是<FONT
color=#990000>operator new</FONT>,也就是内存分配。<FONT
color=#996600><BR>2.</FONT>重载<FONT
color=#990000>operator new</FONT>是一件必须十分小心的事情,在编写MFC程序或者你所编写的系统重载了全局的<FONT
color=#990000>operator new</FONT>时,尤其需要注意,同时应注意所有的#include头文件最好添加在所有define之前,以免造成受到后续对<FONT
color=#990000>new</FONT>的重定义的影响。你可以尝试在你的MFC程序的#define<FONT
color=#990000> new</FONT> DEBUG_NEW一句之后,添加#include<B><FONT
color=#663300> <</FONT></B>vector<B><FONT
color=#663300>></FONT></B>,你会收到一大堆莫名奇妙的错误提示(DEBUG编译时才有),这正是由于#define<FONT
color=#990000> new</FONT> DEBUG_NEW和后面的<FONT
color=#990000>static</FONT><FONT
color=#ff6633> char</FONT> THIS_FILE<B><FONT
color=#663300>[] =</FONT></B> __FILE__<B><FONT
color=#663300>;</FONT></B>造成的影响。<FONT
color=#996600><BR>3.</FONT><FONT
color=#990000>operator new</FONT><B><FONT
color=#663300>/</FONT></B><FONT
color=#990000>delete</FONT>在性质上类似于静态函数,你可以直接通过类名来访问它们。<FONT
color=#996600><BR>4.</FONT>理解了<FONT
color=#990000>operator new</FONT>的基本概念,要理解头文件NEW中的placement<FONT
color=#990000> new</FONT><B><FONT
color=#663300>/</FONT></B><FONT
color=#990000>delete</FONT>的实现也就不是什么难事了,头文件NEW中的placement<FONT
color=#990000> new</FONT><B><FONT
color=#663300>/</FONT></B><FONT
color=#990000>delete</FONT>的实现如下:<FONT
color=#000099><BR>#ifndef __PLACEMENT_NEW_INLINE<BR>#define __PLACEMENT_NEW_INLINE<BR></FONT><FONT
color=#990000>inline</FONT><FONT
color=#ff6633> void</FONT><B><FONT
color=#663300> *</FONT></B>__cdecl<FONT
color=#990000> operator new</FONT><B><FONT
color=#663300>(</FONT></B>size_t<B><FONT
color=#663300>,</FONT></B><FONT
color=#ff6633> void</FONT><B><FONT
color=#663300> *</FONT></B>_P<B><FONT
color=#663300>)<BR> {</FONT></B><FONT
color=#ff0000>return</FONT><B><FONT
color=#663300> (</FONT></B>_P<B><FONT
color=#663300>); }</FONT></B><FONT
color=#000099><BR>#if _MSC_VER >= 1200<BR></FONT><FONT
color=#990000>inline</FONT><FONT
color=#ff6633> void</FONT> __cdecl<FONT
color=#990000> operator delete</FONT><B><FONT
color=#663300>(</FONT></B><FONT color=#ff6633>void</FONT><B><FONT
color=#663300> *,</FONT></B><FONT
color=#ff6633> void</FONT><B><FONT
color=#663300> *)<BR> {</FONT></B><FONT
color=#ff0000>return</FONT><B><FONT
color=#663300>; }</FONT></B><FONT
color=#000099><BR>#endif<BR>#endif<BR></FONT><BR>附:<B><FONT
color=#663300><BR>(</FONT></B>转贴<B><FONT
color=#663300>)</FONT></B>C<B><FONT
color=#663300>++</FONT></B>的各种<FONT color=#990000>new</FONT>简介<FONT
color=#996600><BR><BR>1.</FONT><FONT
color=#990000>new</FONT> T<BR><BR>第一种<FONT
color=#990000>new</FONT>最简单<B><FONT
color=#663300>,</FONT></B>调用类的<B><FONT
color=#663300>(</FONT></B>如果重载了的话<B><FONT
color=#663300>)</FONT></B>或者全局的<FONT
color=#990000>operator new</FONT>分配空间<B><FONT
color=#663300>,</FONT></B>然后用类型后面列的参数来调用构造函数<B><FONT
color=#663300>,</FONT></B>用法是<FONT
color=#990000><BR>new</FONT> TypeName<B><FONT
color=#663300>(</FONT></B>initial_args_list<B><FONT
color=#663300>).</FONT></B><BR>如果没有参数<B><FONT
color=#663300>,</FONT></B>括号一般可以省略<B><FONT
color=#663300>.</FONT></B>例如<FONT
color=#ff6633><BR><BR>int</FONT><B><FONT
color=#663300> *</FONT></B>p<B><FONT
color=#663300>=</FONT></B><FONT color=#990000>new</FONT><FONT
color=#ff6633> int</FONT><B><FONT
color=#663300>;</FONT></B><FONT color=#ff6633><BR>int</FONT><B><FONT
color=#663300> *</FONT></B>p<B><FONT
color=#663300>=</FONT></B><FONT color=#990000>new</FONT><FONT
color=#ff6633> int</FONT><B><FONT
color=#663300>(</FONT></B><FONT color=#999900>10</FONT><B><FONT
color=#663300>);</FONT></B><FONT
color=#ff6633><BR>int</FONT><B><FONT
color=#663300> *</FONT></B>p<B><FONT
color=#663300>=</FONT></B><FONT
color=#990000>new</FONT> foo<B><FONT
color=#663300>(</FONT></B><FONT color=#009900>"hello"</FONT><B><FONT
color=#663300>);</FONT></B><BR><BR>通过调用<FONT
color=#990000>delete</FONT>来销毁<B><FONT
color=#663300>:</FONT></B><FONT
color=#990000><BR>delete</FONT> p<B><FONT
color=#663300>;</FONT></B><FONT color=#996600><BR><BR>2.</FONT><FONT
color=#990000> new</FONT> T<B><FONT
color=#663300>[]</FONT></B><BR>这种<FONT
color=#990000>new</FONT>用来创建一个动态的对象数组<B><FONT
color=#663300>,</FONT></B>他会调用对象的<FONT
color=#990000>operator new</FONT><B><FONT
color=#663300>[]</FONT></B>来分配内存<B><FONT
color=#663300>(</FONT></B>如果没有则调用<FONT
color=#990000>operator new</FONT><B><FONT
color=#663300>,</FONT></B>搜索顺序同上<B><FONT
color=#663300>),</FONT></B>然后调用对象的31m默认构造函数初始化每个对象用法<B><FONT
color=#663300>:</FONT></B><FONT
color=#990000><BR>new</FONT> TypeName<B><FONT
color=#663300>[</FONT></B>num_of_objects<B><FONT
color=#663300>];</FONT></B><BR>例如<FONT
color=#ff6633><BR>int</FONT><B><FONT
color=#663300> *</FONT></B>p<B><FONT
color=#663300>=</FONT></B><FONT color=#990000> new</FONT><FONT
color=#ff6633> int</FONT><B><FONT
color=#663300>[</FONT></B><FONT color=#999900>10</FONT><B><FONT
color=#663300>];</FONT></B><BR>销毁时使用<FONT
color=#990000>operator</FONT> delete31m<B><FONT
color=#663300>[]</FONT></B><FONT
color=#996600><BR><BR>3.</FONT><FONT
color=#990000>new</FONT><B><FONT
color=#663300>()</FONT></B>T 和<FONT
color=#990000>new</FONT><B><FONT
color=#663300>()</FONT></B> T<B><FONT
color=#663300>[]</FONT></B><BR>这是个带参数的<FONT
color=#990000>new</FONT><B><FONT
color=#663300>,</FONT></B>这种形式的<FONT
color=#990000>new</FONT>会调用<FONT
color=#990000>operator new</FONT><B><FONT
color=#663300>(</FONT></B>size_t<B><FONT
color=#663300>,</FONT></B>OtherType<B><FONT
color=#663300>)</FONT></B>来分配内存<B><FONT
color=#663300>,</FONT></B>这里的OtherType要和<FONT
color=#990000>new</FONT>括号里的参数的类型兼容<B><FONT
color=#663300>,</FONT></B>这种语法通常用来在某个特定的地址构件对象<B><FONT
color=#663300>,</FONT></B>称为placement<FONT
color=#990000> new</FONT><B><FONT
color=#663300>,</FONT></B>前提是<FONT
color=#990000>operator new</FONT><B><FONT
color=#663300>(</FONT></B>size_t<B><FONT
color=#663300>,</FONT></B><FONT color=#ff6633>void</FONT><B><FONT
color=#663300>*)</FONT></B>已经定义<B><FONT
color=#663300>,</FONT></B>通常编译器已经提供了一个实现<B><FONT
color=#663300>,</FONT></B>包含<B><FONT
color=#663300><</FONT></B><FONT color=#990000>new</FONT><B><FONT
color=#663300>></FONT></B>头文件即可<B><FONT
color=#663300>,</FONT></B>这个实现只是简单的把参数的指定的地址返回<B><FONT
color=#663300>,</FONT></B>因而<FONT color=#990000>new</FONT><B><FONT
color=#663300
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -