📄 myobject.h
字号:
// MyObject.h: interface for the CMyObject class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(MYOBJ_MYOBJECT_H__E01333D6_46C5_42A5_BC99_5B2E547B5FC1__INCLUDED_)
#define MYOBJ_MYOBJECT_H__E01333D6_46C5_42A5_BC99_5B2E547B5FC1__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
//说明:CMyObject 和 CMyRuntimeClass是从MFC中
//的CObject和CRuntimeClass复制并修改得到的,允许
//在没有引入MFC的情况下实现类对象的动态创建
//
struct CMyRuntimeClass; // object type information
class CMyObject; // the root of all objects classes
#define CLASSID_MY_OBJECT -2
#define CLASSID_NONE -1
#define CLASSID_BASE 0
//如果定义了_MY_OBJ_OPTIMIZE 则每个MyObject的BaseRuntimeClass通过调用取得
//函数GetBaseClass取得,否则使用指针直接访问BaseRuntimeClass
#ifndef CLASS_ALWAYS_VTABLE
#ifndef CLASS_NOVTABLE
#define CLASS_NOVTABLE __declspec(novtable)
#else
#define CLASS_NOVTABLE
#endif
#endif
#define CLASS_COMDAT __declspec(selectany)
/////////////////////////////////////////////////////////////////////////////
// Basic object model
struct CMyRuntimeClass
{
// Attributes
LPCSTR m_lpszClassName;
int m_nObjectSize;
UINT m_wSchema; // schema number of the loaded class
CMyObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
#ifdef _MY_OBJ_OPTIMIZE
CMyRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
CMyRuntimeClass* m_pBaseClass;
#endif
// Operations
CMyObject* CreateObject();
BOOL IsDerivedFrom(const CMyRuntimeClass* pBaseClass) const;
// Implementation
// CMyRuntimeClass objects linked together in simple list
CMyRuntimeClass* m_pNextClass; // linked list of registered classes
long m_lClassID;
long GetClassID() const
{
return m_lClassID;
}
};
/////////////////////////////////////////////////////////////////////////////
// class CMyObject is the root of all compliant objects
#ifdef _MY_OBJ_OPTIMIZE
class CMyObject
#else
class CLASS_NOVTABLE CMyObject
#endif
{
public:
// Object model (types, destruction, allocation)
virtual CMyRuntimeClass* GetRuntimeClass() const;
virtual ~CMyObject()
{
}; // virtual destructors are necessary
// Disable the copy constructor and assignment by default so you will get
// compiler errors instead of unexpected behaviour if you pass objects
// by value or assign objects.
protected:
CMyObject()
{
};
private:
CMyObject(const CMyObject& objectSrc); // no implementation
void operator=(const CMyObject& objectSrc); // no implementation
// Attributes
public:
BOOL IsKindOf(const CMyRuntimeClass* pClass) const;
// Overridables
// Implementation
public:
static const CMyRuntimeClass classCMyObject;
long GetClassID()
{
CMyRuntimeClass* pMyRuntimeClass=GetRuntimeClass();
if(!pMyRuntimeClass)
{
return pMyRuntimeClass->m_lClassID;
};
return CLASSID_NONE;
}
#ifdef _MY_OBJ_OPTIMIZE
static CMyRuntimeClass* PASCAL _GetBaseClass();
#endif
};
// Helper macros
#define GET_RUNTIME_CLASS(class_name) ((CMyRuntimeClass*)(&class_name::class##class_name))
#define MY_ASSERT_KINDOF(class_name, object) \
MY_ASSERT((object)->IsKindOf(GET_RUNTIME_CLASS(class_name)))
// RTTI helper macros/functions
const CMyObject* _cdecl MyDynamicDownCast(CMyRuntimeClass* pClass, const CMyObject* pObject);
CMyObject* _cdecl MyDynamicDownCast(CMyRuntimeClass* pClass, CMyObject* pObject);
#define MY_DYNAMIC_DOWNCAST(class_name, object) \
(class_name*)MyDynamicDownCast(GET_RUNTIME_CLASS(class_name), object)
#ifdef _DEBUG
const CMyObject* _cdecl MyStaticDownCast(CMyRuntimeClass* pClass, const CMyObject* pObject);
CMyObject* _cdecl MyStaticDownCast(CMyRuntimeClass* pClass, CMyObject* pObject);
#define MY_STATIC_DOWNCAST(class_name, object) \
((class_name*)MyStaticDownCast(GET_RUNTIME_CLASS(class_name), object))
#else
#define MY_STATIC_DOWNCAST(class_name, object) ((class_name*)object)
#endif
//////////////////////////////////////////////////////////////////////////////
// Helper macros for declaring CMyRuntimeClass compatible classes
#ifdef _MY_OBJ_OPTIMIZE
#define MY_DECLARE_DYNAMIC(class_name) \
protected: \
static CMyRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static const CMyRuntimeClass class##class_name; \
virtual CMyRuntimeClass* GetRuntimeClass() const; \
#define _MY_DECLARE_DYNAMIC(class_name) \
protected: \
static CMyRuntimeClass* PASCAL _GetBaseClass(); \
public: \
static CMyRuntimeClass class##class_name; \
virtual CMyRuntimeClass* GetRuntimeClass() const; \
#else
#define MY_DECLARE_DYNAMIC(class_name) \
public: \
static const CMyRuntimeClass class##class_name; \
virtual CMyRuntimeClass* GetRuntimeClass() const; \
#define _MY_DECLARE_DYNAMIC(class_name) \
public: \
static CMyRuntimeClass class##class_name; \
virtual CMyRuntimeClass* GetRuntimeClass() const; \
#endif
// not serializable, but dynamically constructable
#define MY_DECLARE_DYNCREATE(class_name) \
MY_DECLARE_DYNAMIC(class_name) \
static CMyObject* PASCAL CreateObject();
#define MY_DECLARE_DYNCREATE_EX MY_DECLARE_DYNCREATE
#define _MY_DECLARE_DYNCREATE(class_name) \
_MY_DECLARE_DYNAMIC(class_name) \
static CMyObject* PASCAL CreateObject();
// generate static object constructor for class registration
#ifdef _MY_OBJ_OPTIMIZE
#define MY_IMPLEMENT_RUNTIMECLASS_EX(class_name, base_class_name, wSchema, pfnNew,clsid) \
CMyRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return GET_RUNTIME_CLASS(base_class_name); } \
const CMyRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL,clsid }; \
CMyRuntimeClass* class_name::GetRuntimeClass() const \
{ return GET_RUNTIME_CLASS(class_name); } \
#define _MY_IMPLEMENT_RUNTIMECLASS_EX(class_name, base_class_name, wSchema, pfnNew,clsid) \
CMyRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return GET_RUNTIME_CLASS(base_class_name); } \
CMyRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL ,clsid}; \
CMyRuntimeClass* class_name::GetRuntimeClass() const \
{ return GET_RUNTIME_CLASS(class_name); } \
///
#define MY_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \
CMyRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return GET_RUNTIME_CLASS(base_class_name); } \
const CMyRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL,CLASSID_NONE }; \
CMyRuntimeClass* class_name::GetRuntimeClass() const \
{ return GET_RUNTIME_CLASS(class_name); } \
#define _MY_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \
CMyRuntimeClass* PASCAL class_name::_GetBaseClass() \
{ return GET_RUNTIME_CLASS(base_class_name); } \
CMyRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
&class_name::_GetBaseClass, NULL ,CLASSID_NONE}; \
CMyRuntimeClass* class_name::GetRuntimeClass() const \
{ return GET_RUNTIME_CLASS(class_name); } \
#else
#define MY_IMPLEMENT_RUNTIMECLASS_EX(class_name, base_class_name, wSchema, pfnNew,clsid) \
const CMyRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
GET_RUNTIME_CLASS(base_class_name), NULL,clsid}; \
CMyRuntimeClass* class_name::GetRuntimeClass() const \
{ return GET_RUNTIME_CLASS(class_name); } \
#define _MY_IMPLEMENT_RUNTIMECLASS_EX(class_name, base_class_name, wSchema, pfnNew,clsid) \
CMyRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
GET_RUNTIME_CLASS(base_class_name), NULL,clsid }; \
CMyRuntimeClass* class_name::GetRuntimeClass() const \
{ return GET_RUNTIME_CLASS(class_name); } \
////////
#define MY_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \
const CMyRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
GET_RUNTIME_CLASS(base_class_name), NULL,CLASSID_NONE}; \
CMyRuntimeClass* class_name::GetRuntimeClass() const \
{ return GET_RUNTIME_CLASS(class_name); } \
#define _MY_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, wSchema, pfnNew) \
CMyRuntimeClass class_name::class##class_name = { \
#class_name, sizeof(class class_name), wSchema, pfnNew, \
GET_RUNTIME_CLASS(base_class_name), NULL,CLASSID_NONE }; \
CMyRuntimeClass* class_name::GetRuntimeClass() const \
{ return GET_RUNTIME_CLASS(class_name); } \
#endif
///////////////////////////////////
#define MY_IMPLEMENT_DYNAMIC_EX(class_name, base_class_name,clsid) \
MY_IMPLEMENT_RUNTIMECLASS_EX(class_name, base_class_name, 0xFFFF, NULL,clsid)
#define MY_IMPLEMENT_DYNCREATE_EX(class_name, base_class_name,clsid) \
CMyObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
MY_IMPLEMENT_RUNTIMECLASS_EX(class_name, base_class_name, 0xFFFF, \
class_name::CreateObject,clsid)
////////////
#define MY_IMPLEMENT_DYNAMIC(class_name, base_class_name) \
MY_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF)
#define MY_IMPLEMENT_DYNCREATE(class_name, base_class_name) \
CMyObject* PASCAL class_name::CreateObject() \
{ return new class_name; } \
MY_IMPLEMENT_RUNTIMECLASS(class_name, base_class_name, 0xFFFF, \
class_name::CreateObject)
// optional bit for schema number that enables object versioning
#define VERSIONABLE_SCHEMA (0x80000000)
/////////////////////////////////////////////////////////////////////////////
// other helpers
// zero fill everything after the vtbl pointer
#define ZERO_INIT_OBJECT(base_class) \
memset(((base_class*)this)+1, 0, sizeof(*this) - sizeof(class base_class));
BOOL WINAPI IsValidAddress( const void* lp, UINT nBytes, BOOL bReadWrite = TRUE );
//DECL_RUNTIME(baseCls,cls,clsid);static CClsRuntimeInfo#cls s_RunTime#cls;
#define DECL_CLASS(baseCls,cls) virtual const char* GetClsName();\
virtual long GetClsId();\
virtual const char* GetClsIdName();
// CClsRuntimeInfo#cls cls::s_RunTime#cls;
#define IMPL_CLASS(baseCls,cls,clsid) const char* cls::GetClsName(){return #cls;};\
long cls::GetClsId(){return clsid;};\
const char* cls::GetClsIdName(){return #clsid;};
#define CLSID_NONE 0
#define GET_CREATOR_PFN(cls) (PROC)cls::CreateThisObj#cls
#define CREATE_NEWOBJ(cls) cls::CreateThisObj#cls()
//#define GET_RUNTIMEINFO(cls) //cls::s_RunTime#cls
#endif // !defined(MYOBJ_MYOBJECT_H__E01333D6_46C5_42A5_BC99_5B2E547B5FC1__INCLUDED_)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -