////////////////////////////////////////////////////////////////// // 类模板运行时类信息支持宏定义 #ifdef _AFXDLL #define IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, pfnNew, class_init) / template < typename type_name > / CRuntimeClass* PASCAL class_name< type_name >::_GetBaseClass() / { return RUNTIME_CLASS(base_class_name); } / template < typename type_name > / AFX_COMDAT const CRuntimeClass class_name< type_name >::class##class_name = { / #class_name, sizeof(class class_name< type_name >), wSchema, pfnNew, / &class_name< type_name >::_GetBaseClass, NULL, class_init }; / template < typename type_name > / CRuntimeClass* PASCAL class_name< type_name >::GetThisClass() / { return _RUNTIME_CLASS_T(class_name, type_name); } / template < typename type_name > / CRuntimeClass* class_name< type_name >::GetRuntimeClass() const / { return _RUNTIME_CLASS_T(class_name, type_name); } / //#define IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, pfnNew, class_init) #define _IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, pfnNew, class_init) / template < typename type_name > / CRuntimeClass* PASCAL class_name< type_name >::_GetBaseClass() / { return RUNTIME_CLASS(base_class_name); } / template < typename type_name > / AFX_COMDAT CRuntimeClass class_name< type_name >::class##class_name = { / #class_name, sizeof(class class_name< type_name >), wSchema, pfnNew, / &class_name< type_name >::_GetBaseClass, NULL, class_init }; / template < typename type_name > / CRuntimeClass* PASCAL class_name< type_name >::GetThisClass() / { return _RUNTIME_CLASS_T(class_name, type_name); } / template < typename type_name > / CRuntimeClass* class_name< type_name >::GetRuntimeClass() const / { return _RUNTIME_CLASS_T(class_name, type_name); } / //#define _IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, pfnNew, class_init) #else #define IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, pfnNew, class_init) / template < typename type_name > / AFX_COMDAT const CRuntimeClass class_name< type_name >::class##class_name = { / #class_name, sizeof(class class_name< type_name >), wSchema, pfnNew, / RUNTIME_CLASS(base_class_name), NULL, class_init }; / template < typename type_name > / CRuntimeClass* class_name< type_name >::GetRuntimeClass() const / { return _RUNTIME_CLASS_T(class_name, type_name); } / //#define IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, pfnNew, class_init) #define _IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, pfnNew, class_init) / template < typename type_name > / AFX_COMDAT CRuntimeClass class_name< type_name >::class##class_name = { / #class_name, sizeof(class class_name< type_name >), wSchema, pfnNew, / RUNTIME_CLASS(base_class_name), NULL, class_init }; / template < typename type_name > / CRuntimeClass* class_name< type_name >::GetRuntimeClass() const / { return _RUNTIME_CLASS_T(class_name, type_name); } / //#define _IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, pfnNew, class_init) #endif ////////////////////////////////// #define IMPLEMENT_TEMPLATE_DYNAMIC(class_name, type_name, base_class_name) / IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, 0xFFFF, NULL, NULL) //#define IMPLEMENT_TEMPLATE_DYNAMIC(class_name, type_name, base_class_name) #define IMPLEMENT_TEMPLATE_DYNCREATE(class_name, type_name, base_class_name) / template < typename type_name > / CObject* PASCAL class_name< type_name >::CreateObject() / { return new class_name< type_name >; } / IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, 0xFFFF, / class_name< type_name >::CreateObject, NULL) //#define IMPLEMENT_TEMPLATE_DYNCREATE(class_name, type_name, base_class_name) #define IMPLEMENT_TEMPLATE_SERIAL(class_name, type_name, base_class_name, wSchema) / template < typename type_name > / CObject* PASCAL class_name< type_name >::CreateObject() / { return new class_name< type_name >; } / extern AFX_CLASSINIT _init_##class_name##type_name; / _IMPLEMENT_TEMPLATE_RUNTIMECLASS(class_name, type_name, base_class_name, wSchema, / class_name< type_name >::CreateObject, &_init_##class_name##type_name) / AFX_CLASSINIT _init_##class_name##type_name(RUNTIME_CLASS_T(class_name, type_name)); / template < typename type_name > / CArchive& AFXAPI operator>>(CArchive& ar, class_name< type_name >* &pOb) / { pOb = (class_name< type_name >*) ar.ReadObject(RUNTIME_CLASS_T(class_name, type_name)); / return ar; } / //#define IMPLEMENT_TEMPLATE_SERIAL(class_name, type_name, base_class_name, wSchema)
用法:
template <class BASE_TYPE = CWnd> class TWnd : public TBase<BASE_TYPE> ////////////////////////////////////////////////////////////////// { DECLARE_DYNAMIC(TWnd) // ...... }; IMPLEMENT_TEMPLATE_DYNAMIC(TWnd, BASE_TYPE, TBase) // ......