Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

Example Analysis of C++ 's complete Runtime Type Information

2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

What this article shares with you is an example analysis of C++ 's complete runtime type information. I think it's very practical, so I share it with you. I hope you can get something after reading this article. Let's take a look at it with the editor.

As we all know, code ape writing code, naturally requires rigorous and careful, but imagination is also very important. After reading the code for decades, we feel that the brains of many apes have been greatly imprisoned, and few people can cross the line, especially the students of C++, together with the old man on the committee, are very speechless, from the works of these people, they all look like dead fish eyes, thousands of people, and no smart life at all. Stl,boost these libraries are like this (although they do accomplish most everyday tasks), not to mention other libraries, there is nothing refreshing.

Just talk about dynamic type information, or reflection. Of course, the waste type_info provided by the language itself is too lazy to say, except to prove that C++ can also imitate and support dynamic information, it is useless, who would seriously do something serious with type_info. Therefore, all kinds of people have to make up for the lack of C++ in the runtime type information. Because the type of reflection information is really too important, that is to say, there are too many opportunities for reflection to show its ability, on the surface, many things do not need reflection, or literal code can not see the trace of reflection, but the inner realization, a lot of reflection is glowing. Just because C++ insists on not giving a little extra support to dynamic information does not mean that C++ does not need reflection. Take a look at the Standard Library, a model of trying to avoid dynamic polymorphism, what a failed work it is. Um, let's talk about this later. If stl did not repel dynamic polymorphism so vigorously from the beginning, you can see that even the memory allocation of allocator can be done in static type information (the latest version of C++ finally has to accept the polymorphic allocator,c++ world is cheered and encouraged, really sad), today's C++ will not cut territory everywhere in many fields to seek peace.

Generally speaking, the C++ reflection libraries on the market now are all intrusive, and they all learn the set of mfc, which are all required to be inherited from a base class Object, before they can provide the function of reflective information to the outside world, not to mention whether the type information they provide is complete, so that the wide range of uses is limited to a very narrow small circle. These reflection libraries, 1, can not reflect the basic types, int, char, double, const char*, … 2. Cannot reflect class or struct,3 that is not inherited from Object, nor can it reflect template classes, such as vector, list. Although typeid is a thousand weak chickens, it is not useless, at least non-invasive, equal and polymorphic. Therefore, the ideal reflection should be as colorless and tasteless as C++ 's native typeid: 1, non-intrusive; 2, can provide reflection for all types, basic type, non-Object struct or class, template type; 3, polymorphic, as long as the change type requires runtime type recognition, then return its own type (subclass) rather than literally declared type 4. Type parameters are supported, that is, when the type is passed to the function, the corresponding type information object is returned.

To be more specific, the reflection library we are asking for is like this. Of course, the first thing to do is to have a type information object TypeInfo, which is filled with all the details about the type. As follows: it can be guessed that this reflective framework only supports single inheritance, which is intentional.

Struct TypeInfo {public: template void ConstructObject (void* obj, MemoryAllocator* alloc, Args&& args) const; bool IsDerviedOf (const TypeInfo* base) const; public: virtual TIType GetTIType () const = 0; virtual const InterfaceMap* GetInterfaces () const; virtual jushort GetMemorySize () const; virtual ConstText GetName () const; virtual AString GetFullName () const; virtual jushort GetAlignSize () const; virtual ConstText GetSpaceName () const; virtual const TypeInfo* GetBaseTypeTI () const; virtual const TypeInfo* GetPointeedTI () const Virtual size_t GetHashCode (const void* obj) const; virtual bool IsValueType () const {return true;} virtual bool IsClass () const {return true;} virtual bool DoInitAllocator (void* obj, MemoryAllocator* memAlloc) const; virtual bool NeedDestruct () const {return false;} virtual void DoDefaultConstruct (void* obj) const; virtual bool CanDefaultConstruct () const {return true;} virtual void DoAssign (void* dest, const void* src) const; virtual bool Equals (const void* objA, const void* objB) const Virtual void DoDestruct (void* obj) const;}

Then, there will be a function TypeOf, which should be two, one is a type template function without parameters, which can be called like this, TypeOf (), and the other is a type template function with one parameter, which can be called like this, TypeOf (obj). No matter which one, the return result is const TypeInfo*. What TypeOf does is that for each type, there is and only one unique TypeInfo object corresponds to it, whether template or non-template; for example, the following judgments must be true.

TypeOf () = = TypeOf ()

TypeOf () = = TypeOf (n); / / n is an integer

TypeOf () = TypeOf (nums); / / the type of nums is vector

Object* a = new ObjectA; TypeOf (a) = = TypeOf ()

In fact, the principle is nothing magical, but trait with sfine, and then all are coolies, that is, for each type is dedicated to a detailed description of the type object, with macros can save a lot of code. But the entire reflection library, we have reconstructed more than a dozen times, and now we are still in the process of refactoring, and we have finally solved all kinds of things encountered in the development. For example, serialization (pointer support, polymorphism support), object and xml interchange, object and json interchange, database table read and write objects, formatting, Any types, non-intrusive interfaces, message sending, string generation objects, and so on.

Its implementation, to sum up, is to introduce the indirect layer element function TypeInfoImp to return a function of type type,type with a GetTypeInfo () in it. Then TypeOf calls GetTypeInfo () of type in TypeInfoImp to finally get the TypeInfo object. The code is as follows.

Template struct TypeInfoImp {typedef Ty type; static const bool value = THasGetTypeInfoMethod::value;}; template struct TypeInfoImp: public TypeInfoImp {typedef typename TypeInfoImp::type type; static const bool value = TypeInfoImp::value;}; template const TypeInfo* TypeOf () {typedef typename TypeInfoImp::type TypeInfoProvider; return TypeInfoProvider::GetTypeInfo ();} template const TypeInfo* TypeOf (const Ty& obj) {typedef typename IsRttiType::type is_rtti / / another indirect layer, dealing with return ImpTypeOf (obj, is_rtti ()) for dynamic types and non-dynamic types respectively;} template struct TypeInfoImp

< bool >

{static const bool value = true; typedef TypeInfoImp type; static TypeInfo* GetTypeInfo ();}; TypeInfo* TypeInfoImp::GetTypeInfo () {static TypeInfo* ti = CreateNativeTypeInfo ("bool"); return ti;}

There may be a concise approach, such as not requiring the introduction of TypeInfoImp, but the TypeInfoImp approach turns out to be the most flexible and code-saving. At the very least, it is very convenient in the custom struct or class, as long as the struct contains a function of GetTypeInfo (), it can be incorporated into the TypeOf system, very convenient. For template-type TypeInfoImp, hash tables are about to be used. For example, for the type information of std::paira, the following implementation

Templatestruct TypeInfoImp

< std::pair >

{static const bool value = true;typedef TypeInfoImp

< std::pair >

Type;static TypeInfo* GetTypeInfo () {ParamsTypeInfo args;return PodPair::LookupTemplateTypeInfo (args);}}

The const TypeInfo*, generation array whose type parameters are extracted. Use this array to look in the hash table of PodPair. If the hash table has an object with this type of array parameter, it will be returned, otherwise see create an add a hash entry, and then return. Each generic type, such as vector,list,pair, has its own hash table.

Finish the job. The principle is simple, but for industrial reflection libraries, there are many details to consider, such as memory management of TypeInfo objects, how to generate a pile of strings for enum types to support the conversion of strings and Destructors, generate and save constructors and destructor pointers for class, support for namespaces, and attribute in emulation C # How to generate member fields or member function information in the most convenient way, in a word, is fucking manual work. However, the reward is very rich, after the coolie work here is done, the rest of the program, basically, there is no repetition of similar code, all the manual work can be pressed on the type information here.

The above is an example analysis of C++ 's complete runtime type information. The editor believes that there are some knowledge points that we may see or use in our daily work. I hope you can learn more from this article. For more details, please follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report