RUNTIME CLASS 執行時間類)

2021-06-20 18:43:21 字數 3272 閱讀 7674

學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...