MFC的Cobject基类及其派生类获取运行时类信息

9 篇文章 0 订阅
MFC的CObject基类提供了运行时类信息的功能,通过CRuntimeClass结构体封装了类名、大小、schema等信息。DECLARE_DYNAMIC宏帮助派生类实现GetRuntimeClass等方法,允许在运行时获取类信息,进行对象创建、类名检查等操作。博客详细介绍了CObject和CRuntimeClass的使用,以及如何通过它们实现多态性。
摘要由CSDN通过智能技术生成

MFC的CObject基类定义有public的virtual CRuntimeClass *GetRuntimeClass() const;是用来返回多态运行时类信息的虚方法,将运行时类信息封装进了结构体CRuntimeClass中

// class CObject is the root of all compliant objects

class AFX_NOVTABLE CObject
{
public:

// Object model (types, destruction, allocation)
	virtual CRuntimeClass* GetRuntimeClass() const;
	virtual ~CObject() = 0;  // virtual destructors are necessary

	// Diagnostic allocations
	void* PASCAL operator new(size_t nSize);
	void* PASCAL operator new(size_t, void* p);
	void PASCAL operator delete(void* p);
	void PASCAL operator delete(void* p, void* pPlace);

#if defined(_DEBUG) && !defined(_AFX_NO_DEBUG_CRT)
	// for file name/line number tracking using DEBUG_NEW
	void* PASCAL operator new(size_t nSize, LPCSTR lpszFileName, int nLine);
	void PASCAL operator delete(void *p, LPCSTR lpszFileName, int nLine);
#endif

	// 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:
	CObject();
private:
	CObject(const CObject& objectSrc);              // no implementation
	void operator=(const CObject& objectSrc);       // no implementation

// Attributes
public:
	BOOL IsSerializable() const;
	BOOL IsKindOf(const CRuntimeClass* pClass) const;

// Overridables
	virtual void Serialize(CArchive& ar);

#if defined(_DEBUG) || defined(_AFXDLL)
	// Diagnostic Support
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

// Implementation
public:
	static const CRuntimeClass classCObject;    //类的静态属性,类属性,包含当前类的类名的CRuntimeClass结构体
#ifdef _AFXDLL
	static CRuntimeClass* PASCAL _GetBaseClass();
	static CRuntimeClass* PASCAL GetThisClass();
#endif
};

结构体CRuntimeClass最直接的内容就是运行时类的类名LPCSTR m_lpszClassName:


struct CRuntimeClass
{
// Attributes
	LPCSTR m_lpszClassName;
	int m_nObjectSize;
	UINT m_wSchema; // schema number of the loaded class
	CObject* (PASCAL* m_pfnCreateObject)(); // NULL => abstract class
#ifdef _AFXDLL
	CRuntimeClass* (PASCAL* m_pfnGetBaseClass)();
#else
	CRuntimeClass* m_pBaseClass;
#endif

// Operations
	CObject* CreateObject();
	BOOL IsDerivedFrom(const CRuntimeClass* pBaseClass) const;

	// dynamic name lookup and creation
	static CRuntimeClass* PASCAL FromName(LPCSTR lpszClassName);
	static CRuntimeClass* PASCAL FromName(LPCWSTR lpszClassName);
	static CObject* PASCAL CreateObject(LPCSTR lpszClassName);
	static CObject* PASCAL CreateObject(LPCWSTR lpszClassName);

// Implementation
	void Store(CArchive& ar) const;
	static CRuntimeClass* PASCAL Load(CArchive& ar, UINT* pwSchemaNum);

	// CRuntimeClass objects linked together in simple list
	CRuntimeClass* m_pNextClass;       // linked list of registered classes
	const AFX_CLASSINIT* m_pClassInit;
};

class DerivedClass:public CObject
{
    DECLARE_DYNAMIC(DerivedClass);
    //剩余类定义
}

所有派生自CObject基类的类可以在类内使用MFC提供的宏“DECLARE_DYNAMIC(DeriveClass);”自动实现静态方法_GetBaseClass()、静态属性class_name、静态方法GetThisClass()和虚方法virtual CRuntimeClass* GetRuntimeClass() const;的定义:


#ifdef _AFXDLL
#define DECLARE_DYNAMIC(class_name) \
protected: \
	static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
	static const CRuntimeClass class##class_name; \
	static CRuntimeClass* PASCAL GetThisClass(); \
	virtual CRuntimeClass* GetRuntimeClass() const; \

#define _DECLARE_DYNAMIC(class_name) \
protected: \
	static CRuntimeClass* PASCAL _GetBaseClass(); \
public: \
	static CRuntimeClass class##class_name; \
	static CRuntimeClass* PASCAL GetThisClass(); \
	virtual CRuntimeClass* GetRuntimeClass() const; \

#else
#define DECLARE_DYNAMIC(class_name) \
public: \
	static const CRuntimeClass class##class_name; \
	virtual CRuntimeClass* GetRuntimeClass() const; \

#define _DECLARE_DYNAMIC(class_name) \
public: \
	static CRuntimeClass class##class_name; \
	virtual CRuntimeClass* GetRuntimeClass() const; \

#endif

派生类实例可以调用GetRuntimeClass()虚方法得到运行时类的信息,最重要的是运行时类类名:

BaseClass *pobj=new DerivedClass();
CRuntimeClass *pRunClass=pobj->GetRuntimeClass();    //DerivedClass的CRuntimeClass
std::string strRunClass = pRunClass->m_lpszClassName;//"DerivedClass"

CObject cobj=CObject();
bool bBaseClass = pRunClass->IsDerivedFrom(cobj.GetRuntimeClass());   //确定派生链上的基类

//以及根据指定类名(派生自CObject基类的)创建实例并返回一个指向该实例的CObject基类指针:
CObject *pcobj=pobj->CreateObject((LPCSTR)strRunClass);

//以及返回指定类名的类的CRuntimeClass结构体:
CRuntimeClass *pRunClass2=pRunClass->FromName((LPCSTR)_T("DerivedClass"));



//以及获取直接基类与当前类的CRuntimeClass结构体指针:
//CRuntimeClass *pBaseClass = pRunClass->_GetBaseClass();
CRuntimeClass *pBaseClass = pRunClass->m_pfnGetBaseClass(); //获取指针类型
CRuntimeClass *pThisClass = obj.GetThisClass();    //获取指针类型

//以及派生自当前类的派生类的CRuntimeClass结构体指针:
CRuntimeClass *pNextClass = pRunClass->m_pNextClass;    //没有就是nullptr

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值