六月婷婷综合激情-六月婷婷综合-六月婷婷在线观看-六月婷婷在线-亚洲黄色在线网站-亚洲黄色在线观看网站

明輝手游網中心:是一個免費提供流行視頻軟件教程、在線學習分享的學習平臺!

探察RUNTIME_CLASS之類的隱秘

[摘要]學mfc學到文檔,視圖和框架的時候,知道必須在這三個類的派生類的類聲明 里加上DECLARE_DYNCREATE,然后在類聲明外合適的地方加上IMPLEMENT_DYNCREA TE,然后文檔,視圖...
學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)
但這個classCView是什么意思?原來,classCView是由DECLARE_DYNAMIC(CView)
引入的一個public屬性的CRuntimeClass類型的靜態成員變量:
static const AFX_DATA CRuntimeClass classCView;

原來RUNTIME_CLASS的作用就是引用由DECLARE_DYNAMIC宏引入的靜態成員變
量。

2。DECLARE_DYNAMIC(class_name)
由于篇幅的原因,宏的具體定義代碼就不列出來了,感興趣的可以去看文件
afx.h。
該宏往類中聲明了三個成員:
protected:
static CRuntimeClass* PASCAL _GetBaseClass();
public:
virtual CRuntimeClass* GetRuntimeClass() const;
static const AFX_DATA CRuntimeClass class##class_name;

有兩個成員函數,一個靜態成員變量class+類名,同RUNTIME_CLASS相似,如
果是DECLARE_DYNAMIC(CView)的話,這個靜態成員變量將是classCView?梢娺@
個成員變量的名稱是和DECLARE_DYNAMIC的參數有關的。在下文我們把這個成員變
量統統記做class##class_name。


這個靜態成員和兩個成員函數在哪里被初始化和具體實現呢?原來是在IMPL
EMENT_DYNAMIC宏里。

3。IMPLEMENT_DYNAMIC(class_name, base_class_name)
查看它的宏定義,如果_AFXDLL被定義了的話,由DECLARE_DYNAMIC引入的成
員的初始化和實現是這樣的:

CRuntimeClass* PASCAL class_name::_GetBaseClass()
{
return RUNTIME_CLASS(base_class_name);
}
CRuntimeClass* class_name::GetRuntimeClass() const
{
return RUNTIME_CLASS(class_name);
}
AFX_COMDAT const AFX_DATADEF
CRuntimeClass class_name::class##class_name =
{
#class_name,
sizeof(class class_name),
0xFFFF,
NULL,
NULL,
&class_name::_GetBaseClass,
NULL
};//這是在初始化靜態成員變量class##class_name。
//CRuntimeClass結構的各個成員的意義可查看msdn。


4。_DECLARE_DYNAMIC(class_name)
該宏的定義和DECLARE_DYNAMIC(class_name)基本一樣。不同之處是靜態成員
class##class_name前面沒有const修飾符。

5。DECLARE_DYNCREATE(class_name)

該宏也往類中引入了DECLARE_DYNAMIC宏所引入的那三個成員。除此之外,它
還另外引入了一個成員:
static CObject* PASCAL CreateObject();
該宏引入的成員在IMPLEMENT_DYNCREATE里初始化和實現。

6。IMPLEMENT_DYNCREATE(class_name, base_class_name)
該宏自然是初始化和實現由DECLARE_DYNCREATE引入的成員了。
我們看看CreateObject的實現:
CObject* PASCAL class_name::CreateObject()
{
{
return new class_name;
}
呵,這個函數是如此簡單,它就是用CObject類里重載的new操作符創建一個
該類類型的對象。

7。_DECLARE_DYNCREATE(class_name)
該宏引入了和DECLARE_DYNCREATE引入的四個成員差不多的成員。唯一的區別
是該宏引入的靜態成員class##class_name前面沒有const修飾符。

8。DECLARE_SERIAL(class_name)
該宏引入了和_DECLARE_DYNCREATE所引入的一樣的四個成員,另外它還多了
這么一句:
AFX_API friend CArchive& AFXAPI operator>>(CArchive& ar, class_name* &
pOb);
原來是把重載操作符operator>>的函數當作該類的友元。于是在操作符函數oper
ator>>中就可以訪問該類的成員了。

9。IMPLEMENT_SERIAL(class_name, base_class_name, wSchema)
該宏初始化了成員變量:
CRuntimeClass class_name::class##class_name=
{
#class_name,
sizeof(class class_name),
wSchema,
class_name::CreateObject),
RUNTIME_CLASS(base_class_name),
NULL
};//在這里,class##class_name前面是沒有const修飾符的。

該宏還實現了下列函數:
CObject* PASCAL class_name::CreateObject()
{
return new class_name;
}

CRuntimeClass* class_name::GetRuntimeClass() const
{
return RUNTIME_CLASS(class_name);
}

CArchive& AFXAPI operator>>
(CArchive& ar, class_name* &pOb)
{
pOb=(class_name*)ar.ReadObject(RUNTIME_CLASS(class_name));
return ar;
}

該宏還聲明了一個函數原型:
AFX_CLASSINIT _init_##class_name(RUNTIME_CLASS(class_name)); 


主站蜘蛛池模板: 午夜一级视频 | 四虎影院在线播放 | 亚洲永久免费网站 | 全黄性色大片 | 亚洲成人高清在线 | 四虎网址在线 | 天天干天天干天天操 | 日韩亚洲欧美在线观看 | 日韩 欧美 中文 亚洲 高清 在线 | 杨幂国产精品福利在线观看 | 日本免费观看视频 | 伊人成人在线观看 | 欧美系列第一页 | 性xxx欧美 | 日韩久久中文字幕 | 日本免费不卡视频一区二区三区 | 三级国产日产 | 日韩免费小视频 | 青青草久热精品视频在线观看 | 亚洲第一免费视频 | 欧美一级视频在线观看 | 青青色在线 | 欧美婷婷| 中文字幕欧美日韩久久 | 午夜视频在线观看免费高清 | 欧美在线观看一区二区三 | 色综久久天天综合绕视看 | 四虎影视国产884a精品亚洲 | 手机在线精品视频每日更新 | 青草热视频 | 特黄女一级毛片 | 亚洲视频在线播放 | 日本一区二区三区在线看 | 日韩a级毛片免费观看 | 色老头网站久久网 | 欧美一区二区三区四区在线观看 | 三级黄色免费 | 亚洲产在线精品第一站不卡 | 四虎国产精品免费久久影院 | 青青青草视频在线观看 | 永久免费看毛片 |