所在的位置: C++ >> C++发展 >> C反射全面解读property

C反射全面解读property

北京手足癣医院专家 http://baidianfeng.39.net/a_zhiliao/210410/8833646.html

导语

本文将深入Property的部分进行介绍,相比较[[reflectionfunctionimplement]],Property涉及的TagDispatch和中间过程更复杂,整体的实现需要一步一步来理清,我们还是从例子入手,从Property的注册和使用来展开整体的实现。

在上篇《C++反射:深入浅出剖析ponder库实现机制!》中我们对反射实现的整体做了相关的介绍,本篇将深入Property的部分进行介绍。

一、Property示例代码

//-------------------------------------//registercode//-------------------------------------__register_typeVector3("Vector3").constructor().constructordouble,double,double().property("x",Vector3::x).property("y",Vector3::y).property("z",Vector3::z));//-------------------------------------//usecode//-------------------------------------auto*metaClass=__type_offramework::math::Vector3();ASSERT_TRUE(metaClass!=nullptr);autoobj=runtime::CreateWithArgs(*metaClass,Args{1.0,2.0,3.0});ASSERT_TRUE(obj!=UserObject::nothing);constreflection::Property*fieldX=nullptr;metaClass-TryProperty("x",fieldX);ASSERT_TRUE(fieldX!=nullptr);doublex=fieldX-Get(obj).Todouble();ASSERT_DOUBLE_EQ(1.0,x);fieldX-Set(obj,2.0);x=fieldX-Get(obj).todouble();ASSERT_DOUBLE_EQ(2.0,x);

上面的代码分为两部分:

(一)注册的代码注册的代码通过__register_typeT()创建的ClassBuilder提供的。property(name,property)函数来完成对属性的注册。(二)使用的代码使用的代码,先获取到MetaClass,再从MetaClass中通过TryProperty()通过名字查询到对应的reflection::Property,然后我们可以通过Property的Get(),Set()方法来对对应UserObject对象的属性进行设置和获取。

(三)整体文章的展开思路

我们的讲述会按照下面的顺序逐步展开:

一些基础知识。

Property运行时的承载对象Property类。

编译期的注册机制。

不同的Property特化实现。

运行时获取值、设置值的具体过程。

二、基础知识

C++中的Property多以MemberObject的方式表达,MemberObject的类型和处理方式比较特殊。以framework::math::Vector3举例:

Vector3的成员变量定义如下:

classVector3{public:doublex;doubley;doublez;};

以下代码是用来获取成员变量y的:

//usingMemberType=double(framework::math::Vector3::*);usingMemberType=doubleframework::math::Vector3::*;MemberTypetmppy=framework::math::Vector3::y;framework::math::Vector3tmpvec(1.0,2.0,3.0);autotmpy=tmpvec.*tmppy;简单总结如下:

通过T(C::)或者TC::来表达成员变量的类型,如上例中的double(Framework::math::Vector3::)。

通过成员变量取地址的方式获取对应成员的地址,如上例中的framework::math::Vector3::y。

如上例中,可以通过tmpvec.tmppy这种获取方式来获取对应对象中的成员(获取的是tmpvec.y的值)。

正常如果不是实现反射,很少使用相关的特性。

三、运行时属性的表达-Property类

为了实现运行时Property,所有的Property需要进行类型擦除,以一致的外观进行组织和调用,framework中的Property实现如下(节选):

classProperty:publicType{public:IdReturnname()const;ValueKindkind()const;virtualboolIsReadable()const;virtualboolIsWritable()const;ValueGet(constUserObjectobject)const;voidSet(constUserObjectobject,constValuevalue)const;inlineTypeIdtype_index()const{returntype_index_;}inlineautoimplement_type()const{returnimplement_type_;}protected:virtualValueGetValue(constUserObjectobject)const=0;virtualvoidSetValue(constUserObjectobject,constValuevalue)const=0;};

主要使用的是Get(),Set()两个方法,用于从UserObject中获取和设置指定Property的值。

四、依赖的核心机制

虽然Property整体的机制比较复杂,但核心依赖的机制实现比较简洁,主要依赖的是ValueBinder和ValueBinder2,以及与这两者基本一致的InternetRefBinder和InternetRefBinder2模板类。

(一)ValueBinder和ValueBinder2

ValueBinder的实现如下图所示:

上图中还有个依赖的Binding对象,具体的信息如下:

相关的Function和Member的Traits我们下文中会具体展开,本部分主要


转载请注明:http://www.aierlanlan.com/tzrz/483.html

  • 上一篇文章:
  •   
  • 下一篇文章: 没有了