 |
句柄大讨论(请各抒己见:)
|
|
| |
| 在Windows程序设计中,句柄是无法精确定义的术语。随便找一个高手,让他给你讲讲句柄是什么,恐怕他都很难给你一个具体的定义来。
在Windows程序设计中,句柄无所不在,窗口有窗口的句柄HWND,线程和进程也有句柄HANDLE,甚至有人把套接字也称为句柄(我就是这样的)。
句柄在英文中是handle,作为动词讲是处理的意思。简而言之,句柄是处理对象的一个接口,对于程序中所涉及的对象,你可以通过句柄去操作他。你不应该试图去回答句柄是什么,而应该从务虚的角度去理解他,知道他干什么即可。
有人说,因为handle的定义是void *,因此他是一个指针。有些熟悉内核的人说这是一个索引。这些说法都是不准确的。需要注意的是,微软并没有精确定义句柄的含义,也许在某个特殊的操作系统中,他使用了一种内部含义,但是在其他版本中,就不保证这样了。任何对句柄的内在假设都可能导致灾难性的后果。
API是接口,句柄是接口,两者有什么区别?API是一个通用的函数族,他处理所有的对象,而句柄是和某个具体对象相关联的数据结构。只有借助句柄,API才知道处理哪个对象。
有些对象有ID。句柄表示特殊的对象,ID也表示某个对象,为什么要两个东西来表示?
首先,句柄不能唯一表示对象。一个对象可以有多个句柄。例如:假设我们用CreateProcess创建一个进程,该进程的第一个线程的句柄会返回给 ...
|
|
| 作者:阿荣 kgj2008张贴于2007-05-14 10:15:40.0,共阅读2106次,回复4次 |
|
|
 |
深入理解C语言指针的奥秘
|
|
| |
| 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址。 要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的 类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区。让我们分别说明。
先声明几个指针放着做例子:
例一:
(1)int*ptr;
(2)char*ptr;
(3)int**ptr;
(4)int(*ptr)[3];
(5)int*(*ptr)[4];
指针的类型
从语法的角度看,你只要把指针声明语句里的指针名字去掉,剩下的部分就是这个指针的类型。这是指针本身所具有的类型。让我们看看例一中各个指针的类型:
(1)int*ptr;//指针的类型是int*
(2)char*ptr;//指针的类型是char*
(3)int**ptr;//指针的类型是int**
(4)int(*ptr)[3];//指针的类型是int(*)[3]
(5)int*(*ptr)[4];//指针的类型是int*(*)[4]
怎么样?找出指针的类型的方法是不是很简单?
指针所指向的类型
当你通过指针来访问指针所指向的内存区时,指针所指向的类型决定了编译器将把那片内存区里的内容当做什么来看待。
从语法上看,你只须把指针声明语句中的指针名字和名字左边的指针声明符*去掉,剩下的就是指针所指向的类型。 ...
|
|
| 作者:不祥 iter张贴于2007-06-13 17:03:44.0,共阅读2008次,回复2次 |
|
|
 |
虚函数表
|
|
| |
| 每个含有虚函数的类有一张虚函数表(vtbl),表中每一项指向一个虚函数的地址,实现上是一个函数指针的数组。 虚函数表既有继承性又有多态性。每个派生类的vtbl继承了它各个基类的vtbl,如果基类vtbl中包含某一项,则其派生类的vtbl中也将包含同样的一项,但是两项的值可能不同。如果派生类重载(override)了该项对应的虚函数,则派生类vtbl的该项指向重载后的虚函数,没有重载的话,则沿用基类的值。在类对象的内存布局中,首先是该类的vtbl指针,然后才是对象数据。在通过对象指针调用一个虚函数时,编译器生成的代码将先获取对象类的vtbl指针,然后调用vtbl中对应的项。对于通过对象指针调用的情况,在编译期间无法确定指针指向的是基类对象还是派生类对象,或者是哪个派生类的对象。但是在运行期间执行到调用语句时,这一点已经确定,编译后的调用代码能够根据具体对象获取正确的vtbl,调用正确的虚函数,从而实现多态性。 分析一下这里的思想所在,问题的实质是这样,对于发出虚函数调用的这个对象指针,在编译期间缺乏更多的信息,而在运行期间具备足够的信息,但那时已不再进行绑定了,怎么在二者之间作一个过渡呢?把绑定所需的信息用一种通用的数据结构记录下来,该数据结构可以同对象指针相联系,在编译时只需要使用这个数据结构进行抽象的绑定,而在运行期间将会得到真正的绑定。这个数据结构就是vtbl。可以看到,实现用 ...
|
|
| 作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读1370次,回复2次 |
|
|
 |
AfxBeginThread和CreateThread具体区别
|
|
| |
| 具体说来,CreateThread这个 函数是windows提供给用户的 API函数,是SDK的标准形式,在使用的过程中要考虑到进程的同步与互斥的关系,进程间的同步互斥等一系列会导致操作系统死锁的因素,用起来比较繁琐一 些,初学的人在用到的时候可能会产生不可预料的错误,建议多使用AfxBeginThread,是编译器对原来的CreateThread函数的封装,用 与MFC编程(当然,只要修改了项目属性,console和win32项目都能调用)而_beginthread是C的运行库函数。 在使用AfxBeginThread时,线程函数的定义为:UINT _yourThreadFun(LPVOID pParam)参数必须如此 在使用CreateThread时,线程的函数定义为: DWORD WINAPI _yourThreadFun(LPVOID pParameter)。 两个的实质都是一样的,不过AfxBeginThread返回一个CWinThread的指针,就是说他会new一个CWinThread对象,而且这个对象是自动删除的(在线程 运行结束时),给我们带来的不便就是无法获得它的状态,因为随时都有可能这个指针指向的是一个已经无效的内存区 域,所以使用时(如果需要了解它的运行状况的话)首先CREATE_SU ...
|
|
| 作者:流水 liushuiwu张贴于2008-12-30 03:30:09.0,共阅读61次,回复0次 |
|
|
 |
VC常见数据类型转换详解
|
|
| |
| VC常见数据类型转换详解我们先定义一些常见类型变量借以说明 int i = 100; long l = 2001; float f=300.2; double d=12345.119; char username[]="女侠程佩君"; char temp[200]; char *buf; CString str; _variant_t v1; _bstr_t v2; ////////////////////////////////////////// 一、其它数据类型转换为字符串 短整型(int) itoa(i,temp,10);///将i转换为字符串放入temp中,最后一个数字表示十进制 itoa(i,temp,2); ///按二进制方式转换 长整型(long) ltoa(l,temp,10); ////////////////////////////////////////// 二、从其它包含字符串的变量中获取指向该字符串的指针 CString变量 str = "2008北京奥运"; buf = (LPSTR)(LPCTSTR)str; BSTR类型的_variant_t变量 v1 = (_bstr_t)"程序员"; buf = _com_util::ConvertBSTRToString( ...
|
|
| 作者:流水 liushuiwu张贴于2008-12-23 04:45:13.0,共阅读95次,回复0次 |
|
|
 |
VC++中使用内存映射文件处理大文件
|
|
| |
| 引言 文件操作是应用程序最为基本的功能之一,Win32 API和MFC均提供有支持文件处理的函数和类,常用的有Win32 API的CreateFile()、WriteFile()、ReadFile()和MFC提供的CFile类等。一般来说,以上这些函数可以满足大多数场合的要求,但是对于某些特殊应用领域所需要的动辄几十GB、几百GB、乃至几TB的海量存储,再以通常的文件处理方法进行处理显然是行不通的。目前,对于上述这种大文件的操作一般是以内存映射文件的方式来加以处理的,本文下面将针对这种Windows核心编程技术展开讨论。 内存映射文件 内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法 ...
|
|
| 作者:流水 liushuiwu张贴于2008-10-12 03:35:17.0,共阅读302次,回复0次 |
|
|
 |
CreateEvent
|
|
| |
| 函数功能描述:创建或打开一个命名的或无名的事件对象 函数原型: HANDLE CreateEvent( LPSECURITY_ATTRIBUTES lpEventAttributes, // 安全属性 BOOL bManualReset, // 复位方式 BOOL bInitialState, // 初始状态 LPCTSTR lpName // 对象名称 ); 参数: lpEventAttributes: [输入]一个指向SECURITY_ATTRIBUTES结构的指针,确定返回的句柄是否可被子进程继承。如果lpEventAttributes是NULL,此句柄不能被继承。 Windows NT/2000:lpEventAttributes的结构中的成员为新的事件指定了一个安全符。如果lpEventAttributes是NULL,事件将获得一个默认的安全符。 bManualReset: [输入]指定将事件对象创建成手动复原还是自动复原。如果是TRUE,那么必须用ResetEvent函数来手工将事件的状态复原到无信号状态。如果设置为FALSE,当事件被一个等待线程释放以后,系统将会自动将事件状态复原为无信号状态。 bInitialState: [输入]指定事件对象的初始状态。如果为TRUE,初始状态为有信号状态;否则为无信 ...
|
|
| 作者:流水 liushuiwu张贴于2008-10-12 02:13:25.0,共阅读260次,回复0次 |
|
|
 |
atoi,atol,strtod,strtol,strtoul实现类型转换
|
|
| |
| atoi,atol,strtod,strtol,strtoul实现类型转换 atof(将字符串转换成浮点型数) 相关函数 atoi,atol,strtod,strtol,strtoul 表头文件 #include <stdlib.h> 定义函数 double atof(const char *nptr); 函数说明 atof()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(’’)才结束转换,并将结果返回。参数nptr字符串可包含正负号、小数点或E(e)来表示指数部分,如123.456或123e-2。 返回值 返回转换后的浮点型数。 附加说明 atof()与使用strtod(nptr,(char**)NULL)结果相同。 atoi(将字符串转换成整型数) 相关函数 atof,atol,atrtod,strtol,strtoul 表头文件 #include<stdlib.h> 定义函数 int atoi(const char *nptr); 函数说明 atoi()会扫描参数nptr字符串,跳过前面的空格字符,直到遇上数字或正负符号才开始做转换,而再遇到非数字或字符串结束时(’ ...
|
|
| 作者:流水 liushuiwu张贴于2008-10-11 05:09:25.0,共阅读514次,回复0次 |
|
|
 |
终于搞懂了,预编译头文件(precompiled header)
|
|
| |
| 预编译头文件今天在改一个很大的程序,慢慢看,慢慢改。突然发现一个.c文件,里面什么也没有,
就几个头文件,我一看,我靠,这不是把简单的问题搞复杂了吗,随手删掉那个c文件。
结果不能编译了,我靠:
fatal error C1083: Cannot open precompiled header file: \'Debug/v13_3.pch\':
No such file or directory
怎么rebuild all都不行。
上网查了一下,才搞懂了:
----------------总结------
如果工程很大,头文件很多,而有几个头文件又是经常要用的,那么
1。把这些头文件全部写到一个头文件里面去,比如写到preh.h
2。写一个preh.c,里面只一句话:#include "preh.h"
3。对于preh.c,在project setting里面设置creat precompiled headers,对于其他
.c文件,设置use precompiled header file
//
哈哈
我试了一下,效果很明显,不用precompiled header,编译一次我可以去上个厕所,用
precompiled header,编译的时候,我可以站起来伸个懒腰,活动活动就差不多啦
---------转载的 ...
|
|
| 作者:不祥 pyl2001张贴于2004-03-09 19:32:16.0,共阅读26973次,回复10次 |
|
|
 |
一个程序中运行可执行文件相关函数详解及示例
|
|
| |
| 一个程序中运行可执行文件相关函数详解及示例
WIN32API函数CreateProcess用来创建一个新的进程和它的主线程,这个新进程运行指定的可执行文件。 函数原型: BOOL CreateProcess ( LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes。 LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation ); lpApplicationName:指向一个NULL结尾的、用来指定可执行模块的字符串。 这个字符串可以使可执行模块的绝对路径,也可以是相对路径,在后一种情况下,函数使用当前驱动器和目录建立可执行模块的路径。 这个参数可以被设为NULL,在这种情况下,可执行模块的名字必须处于 lpCommandLine ...
|
|
| 作者:流水 liushuiwu张贴于2008-10-10 03:45:02.0,共阅读376次,回复0次 |
|
|
 |
学习C/C++的经验谈
|
|
| |
| 工作已经有三年半,算上学校里的时间,大约已有7年的C语言和5年的C++使用经验;熟练使用C/C++也有3年以上;现在的我自认为是可以称得上精通C/C++,基本现在市面上广泛被推崇的经典书籍,如:《C++ Primer》、《高级C++编程技术》、《STL原码剖析》、《Effective C++》、《C编程陷阱》、《Thinking in C++》等等,这些书只有《高级C++编程技术》和《C编程陷阱》在早些时候是通篇看完的(也是因为它们都比较薄),其它的现在基本上都已经不能启发我了,这些书虽然内容各不相同,但针对的读者水平是一样的,应该是已经学会编程语言,能够独立编程但尚未精通,在某些方面存在一定问题或欠缺的人; 对于书籍,我现在的追求又回到了纯理论,基本上是远离编程语言和计算机,比如,小波变换和《Algorithm I-IV》; 言归正传,关于很多人疑问的先学什么后学什么的问题,我认为:如果你选择C++作为最终的工具,或者是以C++为主的,那么我强烈建议你先学习C语言; 首先要说明的是,C和C++是两件截然不同的东西,学习C++可以完全没有C的基础,或者说可以完全不用先学C;但是,这样你是永远也不可能成为真正的C++大师的;你最多只能成为一个C++的熟练工人;C和C++有一个共同的奥义:内存管理,而你不学习C,单从对C++的理解 ...
|
|
| 作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读2513次,回复4次 |
|
|
 |
数组和指针的剖析
|
|
| |
| 数组和指针的剖析
指针到底是什么呢。指针其实可以比作相当于一个寄存器,我们暂且可以这样理解。因为一个寄存器中一般存放的都是一个4字节的内存地址。所以我们的指针同样也是存放的一个内存地址。我们其实在访问指针就是间接的访问内存地址。 转为汇编中相当于 dowrd ptr [指针] 。这样访问的就是指针地址中存储的数据。
很多人说指针和数组时相同的,因为他们认为 例如。
char *string = "hello world";
他们通过string [0] 就可以访问到字符’h’。其实这时存在一个间接的作用。这里我们假设string的内存地址时 00405128。例如这里我们通printf("%c", string[0])。 那么此时程序则会将 dword ptr [string+1] 压入堆栈。 不过因为堆栈一般是通过寄存器操作的所以 mov eax ,dword ptr [string+1] 。因为一般我们汇编中要进行访问内存中的数据的时候,数据地址需要加上 []。 例如 mov eax, 3 和 mov eax, [3] 。显然不同,前者是将立即数3传递到eax寄存器中。后者是将地址3中开始的32位值 传递给eax寄存器。因为一般 ...
|
|
| 作者:xyblack xyblack张贴于2008-03-25 03:41:31.0,共阅读1013次,回复0次 |
|
|
 |
在VC中加载GIF动画
|
|
| |
| 在VC中加载GIF动画
有一个CPictureEx类,用于加载GIF动画,不过该类是mfc封装类,对于不使用mfc的c++程序员来讲,不能使用。为了让该类能够让更多的人方便的使用,使其不再被局限于MFC,本人花时间改造了一下这个类,改造后,该类可以应用于任何MFC、 WTL/ATL及其它WINDOWS API编程。
由于原来的CPictureEx是继承于CStatic类,本人改造后,在CPictureEx中直接封装了一个窗口句柄HWND。
假设您在一个弹出式Dialog对话框中加载gif动画,您要做的就是在对话框中放一个控件,可以是BUTTON、STATIC等等。假设您加的这个控件的ID是IDC_FLASH,您的对话框窗口句柄是hDlg,则要使用CPictureEx,将非常简单。详情参见源代码。
PictureEx图片显示类支持以下格式的图片:GIF (including animated GIF87a and GIF89a), JPEG, BMP, WMF, ICO, CUR等,我特别推崇的是可以做出动画,而且轻而易举,确实很COOL。
下面是详细的编程过程:
1. 新建项目:在VC6中用MFC新建一个基于对话框的GifDemo应用程序,接受所有缺省选项即可;
2.在项目中插入文件:把PictureEx.h,PictureEx.cpp文件copy 到项目 ...
|
|
| 作者:Oleg qiaoyongbo张贴于2007-12-20 15:36:17.0,共阅读1697次,回复3次 |
|
|
 |
VC无闪烁刷屏技术的实现
|
|
| |
| VC无闪烁刷屏技术的实现
在实现绘图的过程中,显示的图形总是会闪烁,笔者曾经被这个问题折磨了好久,通过向高手请教,搜索资料,问题基本解决,现将文档整理出来以供大家参考.
1.显示的图形为什么会闪烁
我们的绘图过程大多放在OnDraw或者OnPaint函数中,OnDraw在进行屏幕显示时是由OnPaint进行调用的。当窗口由于任何原因需要重绘时,总是先用背景色将显示区清除,然后才调用OnPaint,而背景色往往与绘图内容反差很大,这样在短时间内背景色与显示图形的交替出现,使得显示窗口看起来在闪。如果将背景刷设置成NULL,这样无论怎样重绘图形都不会闪了。当然,这样做会使得窗口的显示乱成一团,因为重绘时没有背景色对原来绘制的图形进行清除,而又叠加上了新的图形。有的人会说,闪烁是因为绘图的速度太慢或者显示的图形太复杂造成的,其实这样说并不对,绘图的显示速度对闪烁的影响不是根本性的。例如在OnDraw(CDC *pDC)中这样写:
pDC->MoveTo(0,0);
pDC->LineTo(100,100);
这个绘图过程应该是非常简单、非常快了吧,但是拉动窗口变化时还是会看见闪烁。其实从道理上讲,画图的过程越复杂越慢闪烁应该越少,因为绘图用的时间与用背景清除屏幕所花的时间的比例越大人对闪烁的感觉会越不明显。比如:清楚屏幕时间为1s绘图时间也是为1s,这 ...
|
|
| 作者:不祥 qiaoyongbo张贴于2007-12-20 15:25:50.0,共阅读1217次,回复1次 |
|
|
 |
C++面向程序设计课程习题详解
|
|
| |
|
|
|
| 作者:原野 killer张贴于2007-11-30 21:19:23.0,共阅读978次,回复1次 |
|
|
 |
写一个函数,完成内存之间的拷贝。[考虑问题是否全面]
|
|
| |
| 答:void* mymemcpy( void *dest, const void *src, size_t count ){ char* pdest = static_cast<char*>( dest ); const char* psrc = static_cast<const char*>( src ); if( pdest>psrc && pdest<psrc+cout ) 能考虑到这种情况就行了 { for( size_t i=count-1; i!=-1; --i ) pdest = psrc; } else { for( size_t i=0; i<count; ++i ) pdest = psrc; } return dest;}int main( void ){ char str[] = "0123456789"; mymemcpy( str+1, str+0, 9 ); cout << str << endl; system( "Pause" ); return 0;}本文转载自IT网it求职笔试真题库网。
|
|
| 作者:不祥 oases2008张贴于2005-01-01 00:00:00.0,共阅读2079次,回复2次 |
|
|
 |
重读《Programmer》"C++之父"访谈
|
|
| |
| 一:C++ 的新标准
1998年通过了C++的标准。而新的标准将会再2005年出现。我想到了Whidbey的推迟发步,是否是和这个新的标准有关系。
二:C++与嵌入式软件
嵌入式软件的定义:凡是在非传统的计算机上运行的软件都是属于这个领域。而嵌入式软件开发对PL的根本的要求是:运行时效率,内存使用率,以及可以预测性。而C++可以设计成在资源有限的情形下支持以上的意图。
a. 可预测性
当调用一个virtual函数的时候,其开销是完全可以预测的。同时,在使用局部变量,静态全局域中的对象时,对象开销可以很好预测。
b.内存使用
如需要使用动态的内存,则可以使用内存池;甚至可以使用GC(当然是在没有时间限制的情形下)。
c. 运行效率
使用C++可以设计完全不涉及到OO的代码,同时和标准C的良好的兼容也是选择其的原因。
关于C++运行时的效率问题,可以参考:
http://arubis.dkuug.dk/jtc/sc22/wg21/docs/papers/2002/n1396.pdf
三:Managed C++
Herb Sutter 说 ISO 将会考虑采纳对M C++ 制定国际标准。
Dr. Stroustrup : 每个平台提供商都会对语言进行扩展,以便与平台与OS相兼容。而.NET的平台是和一般的C接口是不同。
四: ...
|
|
| 作者:beick iter张贴于2007-06-13 16:59:45.0,共阅读1367次,回复0次 |
|
|
 |
C++语言风格流变史
|
|
| |
| 我确实没有见过哪一种语言能像C++这样,在代码风格方面表现得如此诡谲和难以捉摸:谁也说不清C++代码究竟能衍生出多少种迥异的风格,但我知道,有许多C++初学者在面对不同风格的C++代码时,经常会误以为自己看到的是好几种完全不同的编程语言??仅此一点就足以提醒我们,研究和廓清C++语言风格的演化和发展规律已是当务之急了。
程序代码也有风格,这算不得什么新鲜事。早在20世纪80年代, C语言程序员就必须在K&R风格和ANSI风格之间择善而从。但平心而论,我确实没有见过哪一种语言能像C++这样,在代码风格方面表现得如此诡谲和难以捉摸:谁也说不清C++代码究竟能衍生出多少种迥异的风格,但我知道,有许多C++初学者在面对不同风格的C++代码时,经常会误以为自己看到的是好几种完全不同的编程语言??仅此一点就足以提醒我们,研究和廓清C++语言风格的演化和发展规律已是当务之急了。
和文体学家们研究历朝历代文体变迁的工作相仿,研究C++语言风格的流变史也没有什么捷径可走。我们只能依据刘勰在《文心雕龙》中提倡的“原始以表末”[1]的研究方法,循着历史的脉络,推求代码风格的来源,探寻风格演化的内因,并借以阐明技术发展的趋势和规律。
1. 带类的C??对C语言风格的因袭
在1983年12月Bjarne Stroustrup采纳Rick Mascitti的建议,将其发明的新语言命名为“C++ ...
|
|
| 作者:王咏刚 iter张贴于2007-06-13 11:30:04.0,共阅读1686次,回复0次 |
|
|
 |
!求助!朋友们请帮忙!!!
|
|
| |
| 最近在学习Visual C++界面编程!
不知道怎样将一段文字显示在EDIT类型的窗口界面上????
不知道调什么函数?还望大家指点!!
本人不尽感激!!
谢谢!!
方便的话清回复邮箱:Romid@163.com
或者直接回复该帖!!
谢谢!!
|
|
| 作者:A*C*C年 Romid张贴于2007-05-17 13:19:49.0,共阅读1587次,回复2次 |
|
|
 |
探察RUNTIME_CLASS的秘密
|
|
| |
| 学mfc学到文档,视图和框架的时候,知道必须在这三个类的派生类的类声明
里加上DECLARE_DYNCREATE,然后在类声明外合适的地方加上IMPLEMENT_DYNCREA
TE,然后文档,视图和框架,还有文档模板就可以协调工作了。查看msdn,发现
类似的宏有这几对:
DECLARE_DYNAMIC 和 IMPLEMENT_DYNAMIC
DECLARE_DYNCREATE 和 IMPLEMENT_DYNCREATE
DECLARE_SERIAL 和 IMPLEMENT_SERIAL
虽然msdn里介绍了他们的作用,但对于它们为什么会起这样的作用心里却没
底,于是翻了翻mfc的源代码,喜欢钻牛角尖的人可以和我一起来钻一钻。
1。
RUNTIME_CLASS宏的定义是这样的:
#define RUNTIME_CLASS(class_name)
((CRuntimeClass*)(&class_name::class##class_name))
其中##的意思是把##两边的符号都进行宏扩展(如果它们是宏的话),然后把扩展
后的内容连接在一起,中间不加空格。例如:RUNTIME_CLASS(CView)将被扩展成
:
(CRuntimeClass*)(&CView::classCView)
但这个classCV ...
|
|
| 作者:chiefman kgj2008张贴于2007-05-14 21:19:42.0,共阅读1764次,回复0次 |
|
|