學mfc學到文件,檢視和框架的時候,知道必須在這三個類的派生類的類宣告
裡加上declare_dyncreate,然後在類宣告外合適的地方加上implement_dyncrea
te,然後文件,檢視和框架,還有文件模板就可以協調工作了。檢視msdn,發現
類似的巨集有這幾對:
declare_dynamic 和 implement_dynamic
declare_dyncreate 和 implement_dyncreate
declare_serial 和 implement_serial
雖然msdn裡介紹了他們的作用,但對於它們為什麼會起這樣的作用心裡卻沒
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()
cruntimeclass* class_name::getruntimeclass() const
afx_comdat const afx_datadef
cruntimeclass class_name::class##class_name =
;//這是在初始化靜態成員變數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()
呵,這個函式是如此簡單,它就是用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##class_name前面是沒有const修飾符的。
該巨集還實現了下列函式:
cobject* pascal class_name::createobject()
cruntimeclass* class_name::getruntimeclass() const
carchive& afxapi operator>>
(carchive& ar, class_name* &pob)
該巨集還宣告了乙個函式原型:
afx_classinit _init_##class_name(runtime_class(class_name));
執行時異常
常見的幾種如下 nullpointerexception 空指標引用異常 classcastexception 型別強制轉換異常。illegalargumentexception 傳遞非法引數異常。arithmeticexception 算術運算異常 arraystoreexception 向陣列中...
執行時改變控制項大小執行時移動控制項MINICAR版
執行時改變控制項大小執行時移動控制項minicar版 vs2005.net編寫,網上找了找,見別人寫得挺複雜,自己寫了乙個.附件居然不能上傳.就把 發到下面吧,有個奇怪現象就是,vb6中新建工建,拖個picturebox框出來,拷入以下 即可,但vb.net中是不行的.如mousemove事件你必須...
VC執行時庫
vc專案屬性 配置屬性 c c 生成 執行時庫 可以採用的方式有 多執行緒 mt 多執行緒除錯 mtd 多執行緒dll md 多執行緒除錯dll mdd 單執行緒 ml 單執行緒除錯 mld reusable library switch library macro s defined single...