mfc的cruntimeclass利用鍊錶實現了c++類的動態建立。但是如果專案中對動態建立的要求比較低,我們完全可以利用map實現簡單的動態建立。以下三個檔案做了乙個簡單的實現。
/*
* author: yejingx
* date: 2011-12-29
* file: base.h
*/#ifndef base_h_
#define base_h_
#include "dyncreate.h"
class base
};public:
base(void);
virtual ~base(void);
virtual void run();
};#endif
/*
* author: yejingx
* date: 2011-12-29
* file: base.cpp
*/#include #include "base.h"
std::mapbase::class_set;
base* base::create(const std::string& class_name) // 動態建立函式實現
return null;
}base::base(void)
public:
derived(void);
virtual ~derived(void);
void run();
};#endif
/*
* author: yejingx
* date: 2011-12-29
* file: derived.cpp
*/#include #include "derived.h"
static derived::_auto_register _register_derived("derived",derived::create); // 宣告乙個靜態變數,自動呼叫它的建構函式對類進行自動註冊
derived::derived(void)};
#define implement_dynbase(base) \
std::mapbase::class_set; \
base* base::create(const std::string& class_name) \
return null; }
#define declare_dyncreate(derived,base) \
public: \
static base* create()
#define implement_dyncreate(derived) \
static derived::_auto_register _register_##derived(#derived,derived::create);
#endif
有了這些巨集,base.h, base.cpp, derived.h和derived.cpp就可以變成以下這樣子。
/*
* author: yejingx
* date: 2011-12-29
* file: base.h
*/#ifndef base_h_
#define base_h_
#include "dyncreate.h"
class base
;#endif
/*
* author: yejingx
* date: 2011-12-29
* file: base.cpp
*/#include #include "base.h"
implement_dynbase(base) // 實現動態建立基類
implement_dyncreate(base) // 實現基類的動態建立
base::base(void);
#endif
/*
* author: yejingx
* date: 2011-12-29
* file: derived.cpp
*/#include #include "derived.h"
implement_dyncreate(derived) // 實現動態建立子類
derived::derived(void) \struct _auto_register };
#define implement_dynbase(base) \
base* base::create(const std::string& class_name) \
return null; }
#define declare_dyncreate(derived,base) \
public: \
static base* create()
#define implement_dyncreate(derived) \
static derived::_auto_register _register_##derived(#derived,derived::create);
#endif
編寫測試檔案
/*
* author: yejingx
* date: 2011-12-29
* file: dyn_test.cpp
*/#include "derived.h"
int main()
輸出
base constructor called
derived constructor called
derived class run
derived destructor called
base destructor called
base constructor called
base class run
base destructor called
到此,我們已經保證在第一次使用class_set前對其進行建立並初始化,但是仍然存在乙個問題。設想,假如我們編寫的程式在_auto_register物件初始化前呼叫了base::create(class_name),這時候的base::class_set是空的,base::create(class_name)就返回乙個空指標!有一次我把base, derived等類打包成乙個lib,然後寫了另外乙個檔案呼叫這個lib中的base::create,就出現了上述問題。之後我用了很土的辦法臨時解決了這個問題,在此不提也罷。
如何確保第一次呼叫base::create之前_auto_register物件都已經建立?期待高手指點。。。
Flex動態建立類物件
自actionscript 3開始,eval函式就被取消了,這樣就不能像原來那樣利用字串動態的建立物件了,但利用函式flash.utils.getdefinitionbyname仍可以根據型別名稱動態地建立類物件例項,下面看乙個例子 輸出結果 dynamicobject is created dyn...
Flex動態建立類物件
flex動態建立類物件 2010年08月07日 之所以會出錯,是因為在flex編譯程式時會自行刪除一些未使用的,這時在動態建立物件時就會因缺失物件的型別而建立失敗。之前的 之所以執行成功,是因為型別dynamicobject在 中顯示地被使用,所以型別資訊dynamicobject在編譯時不會被刪除...
Flex動態建立類物件
flex動態建立類物件 2010年08月07日 之所以會出錯,是因為在flex編譯程式時會自行刪除一些未使用的,這時在動態建立物件時就會因缺失物件的型別而建立失敗。之前的 之所以執行成功,是因為型別dynamicobject在 中顯示地被使用,所以型別資訊dynamicobject在編譯時不會被刪除...