我眼里的RuntimeClass实现

最近开始学习VC了,谈谈心得吧。班门弄斧,请多多指教。

心得之一:

MFC中RuntiemClass支持的实现:

只要是从CObject派生的类,可以轻松实现RuntiemClass支持。当然,是通过编译器提供的宏来实现的。那么其实现机制是怎样的呢?我觉得只需要四个步骤。

首先让我们简化一下CRuntiemClass和CObject的定义,抽取出与RuntiemClass相关的部分:

struct CRuntimeClass
{
 char m_lpszClassName[255];
 int m_nObjectSize;
 CObject* (*m_pfnCreateObject)();
 CObject* CreateObject();
};

class CObject
{
public:
 virtual CRuntimeClass* GetRuntimeClass() const {return NULL;}
 static CRuntimeClass classCObject;
 virtual ~CObject(){};
protected:
 CObject(){printf("CObject constructed/n");}
};

我所说的四个步骤是(下面的操作都是对于从CObject派生的类而言的):

1.添加CRuntiemClass类型的静态成员classCMyClass(请把CMyClass换成你的类名)

        static CRuntimeClass classCMyClass;

2.覆盖父类(即CObject)的GetRuntimeClass()方法,使之返回classCMyClass的指针

3.添加并实现 CreateObject();方法。

  声明: static CObject* CreateObject();

  实现:CObject* CMyClass::CreateObject() { return new CMyClass;  }

4.为classCMyClass赋值。使m_lpszClassName="CMyClass";

    m_nObjectSize=sizeof (CMyClass);

     函数指针m_pfnCreateObject指向CMyClass::CreateObject。

       CRuntimeClass CMyClass::classCMyClass=   {"CMyClass",sizeof (CMyClass),
                                                                        CMyClass::CreateObject};

附上完整的例程(摘自Programming Visual C++6.0 Unleashed):

#include <stdio.h>
#define RUNTIME_CLASS(class_name) (&class_name::class##class_name)

class CObject;
struct CRuntimeClass
{
 char m_lpszClassName[21];
 int m_nObjectSize;
 CObject* (*m_pfnCreateObject)();
 CObject* CreateObject();
};

class CObject
{
public:
 virtual CRuntimeClass* GetRuntimeClass() const {return NULL;}
 static CRuntimeClass classCObject;
 virtual ~CObject(){};
protected:
 CObject(){printf("CObject constructed/n");}
};

CRuntimeClass CObject::classCObject=
    {"CObject",sizeof(CObject),NULL};

CObject* CRuntimeClass::CreateObject()
{
 return (*m_pfnCreateObject)();
}

class CAlpha:public CObject
{
public:
 virtual CRuntimeClass* GetRuntimeClass() const
 {
  return &classCAlpha;
 }
 static CRuntimeClass classCAlpha;
 static CObject* CreateObject();
protected:
 CAlpha(){printf("CAlpha constructor/n");}
};

CRuntimeClass CAlpha::classCAlpha={"CAlpha",sizeof(CAlpha),CAlpha::CreateObject};

CObject* CAlpha::CreateObject()
{
 return new CAlpha;
}

class CBeta:public CObject
{
public:
 virtual CRuntimeClass* GetRuntimeClass() const {return &classCBeta;}
 static CRuntimeClass classCBeta;
 static CObject* CreateObject();
protected:
 CBeta(){printf("CBeta constructed/n");}
};
   CRuntimeClass CMyClass::classCMyClass=   {"CMyClass",sizeof (CMyClass),
    CMyClass::CreateObject};

 

CRuntimeClass CBeta::classCBeta={"CBeata",sizeof(CBeta),CBeta::CreateObject};

CObject* CBeta::CreateObject()
{
 return new CBeta;
}

class CGama:public CObject
{
public:
 virtual CRuntimeClass* GetRuntimeClass() const { return &classCGama;}
 static CRuntimeClass classCGama;
 static CObject* CreateObject();
protected:
 CGama(){printf("CGama constructed/n");}
};

CRuntimeClass CGama::classCGama={"CGama",sizeof(CGama),CGama::CreateObject};

CObject* CGama::CreateObject()
{
 return new CGama();
}

int main()
{
 printf("Entering dynCreate main/n");

 CRuntimeClass* pRTCAlpha=RUNTIME_CLASS(CAlpha);
 CObject* pObj1=pRTCAlpha->CreateObject();
 printf("class of pObj1=%s/n",pObj1->GetRuntimeClass()->m_lpszClassName);
 
 CRuntimeClass* pRTCBeta=RUNTIME_CLASS(CBeta);
 CObject* pObj2=pRTCBeta->CreateObject();
 printf("class of pObj2=%s/n",pObj2->GetRuntimeClass()->m_lpszClassName);

 CRuntimeClass* pRTCGama=RUNTIME_CLASS(CGama);
 CObject* pObj3=pRTCGama->CreateObject();
 printf("class of pObj3=%s/n",pObj3->GetRuntimeClass()->m_lpszClassName);

 
 delete pObj1;
 delete pObj2;
 delete pObj3;

 return 0;
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
如果你使用的是 Scala 2.11.x,那么默认值不生效是由于 fastjson 库在解析时不会调用 Scala 2.11.x 版本中的默认构造函数。这个问题可以通过实现自定义反序列化器来解决。以下是一个示例代码: ```scala import com.alibaba.fastjson.{JSON, JSONObject} import com.alibaba.fastjson.parser.deserializer.ObjectDeserializer import scala.reflect.ClassTag class CaseClassDeserializer[T: ClassTag] extends ObjectDeserializer { override def deserialze(parser: com.alibaba.fastjson.parser.DefaultJSONParser, `type`: scala.reflect.Type, fieldName: Any): T = { val cls = implicitly[ClassTag[T]].runtimeClass val obj = cls.newInstance().asInstanceOf[T] val jsonObj = parser.parseObject() jsonObj.forEach((k, v) => { val field = cls.getDeclaredField(k) field.setAccessible(true) field.set(obj, v) }) obj } override def getFastMatchToken: Int = 0 } object CaseClassDeserializer { def apply[T: ClassTag]: CaseClassDeserializer[T] = new CaseClassDeserializer[T] } case class Person(name: String, age: Int = 18) val json = "{\"name\":\"Alice\"}" val person = JSON.parseObject(json, CaseClassDeserializer[Person].asInstanceOf[ObjectDeserializer]) println(person) // Person(Alice,18) ``` 在这个示例代码中,我们实现了一个 `CaseClassDeserializer` 类,该类实现了 `ObjectDeserializer` 接口,并重写了 `deserialze` 方法。在 `deserialze` 方法中,我们首先通过 `implicitly[ClassTag[T]].runtimeClass` 获取到待解析类的 `Class` 对象,然后使用 `newInstance` 方法创建一个对象实例。接着,我们使用 fastjson 解析 JSON 对象,并遍历其中的键值对。对于每一个键值对,我们通过 `cls.getDeclaredField(k)` 获取到该字段在类中的 `Field` 对象,然后使用 `setAccessible` 方法将其设置为可访问状态,并最终使用 `field.set(obj, v)` 将键值对中的值赋值给该字段。最后,我们将解析出的对象返回。 在代码的最后,我们使用 `JSON.parseObject` 方法解析 JSON 字符串,并将 `CaseClassDeserializer[Person]` 作为反序列化器传入该方法。这里需要使用 `asInstanceOf[ObjectDeserializer]` 将 `CaseClassDeserializer[Person]` 转换为 `ObjectDeserializer` 类型。最终,我们可以得到正确的解析结果,即 `Person(Alice,18)`。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值