C + + simulation implements OBJECTIVE-C dynamic type

Source: Internet
Author: User



In OC (OBJECTIVE-C) There are dynamic types that fall into the following categories:


-(BOOL) isKindOfClass: whether classObj is a classObj class or a subclass of it

-(BOOL) isMemberOfClass: whether classObj is an instance of classObj

-(BOOL) respondsTosSelector: Is this method available in the selector class

NSClassFromString (NSString *); Get class object from string

NSStringFromClass ([class name Class]); get the string from the class name

Class rectClass = [Rectangle class]; Get class object by class name

Class aClass = [anObject class]; Get class object by instance

if ([obj1 class] == [obj2 class]) determines whether it is an instance of the same class





Although C + + itself does not contain these features, but in contrast to C + + is the more basic language, in fact, most of these can also be implemented in C + + simulation. While these may not be significant for practical development, we can also learn a lot about the underlying knowledge of high-level languages in order to gain a deeper understanding of the nature of language or the flexibility of language.



First, let's implement the Iskindofclass function, which in C + + is primarily to determine whether an object is from a class object or a subclass object of a class. We simulate the implementation of this function, if said a-b-c-d-e a series of inheritance, if the following two conditions: 1. Each class has its own identity, which is used to determine whether an object is an object of this class by its identity, and 2. For a-b-c-d-e succession, make a list for query use. So if we need to determine whether the C-C object is a subclass of object, then only need to invoke a query interface, passing in the A object identifier, when the object is a Class A, then query the B object, and then query to the C object, at this time, the judgment through the return to true.


1 // Here we use the class name as the unique identifier, which is the szClassName variable
  2 // then forward and backward two linked lists are used to string the entire inheritance relationship
  3 struct ClassRunTimeType
  4 {
  5 char * szClassName;
  6 static ClassRunTimeType * pFirstClass;
  7 ClassRunTimeType * m_pPrevClassRunTimeType;
  8 ClassRunTimeType * m_pNextClassRunTimeType;
  9 };
10
11 // This class has no other purpose, only need to perform the construction when borrowing the definition object
12 // Initialize the code we need to execute by executing the constructor
13 // Each class will use it to define a corresponding object
14 class CRunTimeType
15 {
16 public:
17 CRunTimeType (ClassRunTimeType * pType);
18}; 


With the above basic data structure, you can then move your feet in the actual class.


 
 
 1 class NSObject
 2 {
 3 public:
 4     virtual void ShowHello(){}
 5 
 6     BOOL isKindOfClass(ClassRunTimeType *pRunTimeType);
 7     BOOL isMemberOfClass(void *pFun);
 8     void *GetInstallFromName(char *szName);
 9 
10     virtual char* GetCurrentClassName()
11     {
12         return NSObject::GetClassName();
13     }
14 
15     static char* GetClassName()
16     {
17         return szClassNSObject;
18     }
19 };
20 
21 static char szClassNSObject[] = "NSObject"; 
22 ClassRunTimeType NSObject::classNSObject = {szClassNSObject,NULL,NULL};





Szclassname[] = "NSObject" is the unique identifier of this class, if you want to determine whether it is from this class, only need to compare the string, the corresponding call method is very simple, that is, BOOL Iskindofclass ( Classruntimetype *pruntimetype) is implemented internally.


 
 
1 BOOL isKindOfClass(ClassRunTimeType *pRunTimeType)
2 {
3     if (0 == strcmp(GetCurrentClassName(),pRunTimeType->szClassName))
4         return TRUE;
5     return FALSE;
6 }


Of course, this time is just to realize that an object is not a class of objects, for is not a subclass or not, because there is no use of the above linked list query function. But believe that this specific how to achieve is not difficult, if there are doubts can be adjusted in this article corresponding source code, there are detailed instructions.



Unfortunately Respondstosselector did not find a good method, first object-c each member function is a virtual function, relatively easy to implement some, and C + + inside the non-virtual function is completely unable to judge. Second, even if the virtual function, there are some difficulties in judging, take VS2010 as an example, in the case of disabling optimization, calling a virtual function will perform the following steps:


 
 
1 ShowHelloEx.ShowHello();
2 00191080  lea         ecx,[ShowHelloEx]  
3 00191083  call        NSObject::ShowHello (191010h)  


First, save the address of this pointer to ECX, which is also the method of the VS series. The next call to the Shewhello function inside, but this is not transferred to the virtual table inside the corresponding address, but transferred to this place


 
1 NSObject::`vcall‘{0}‘:
2 00191140  mov         eax,dword ptr [ecx]  
3 00191142  jmp         dword ptr [eax]  


Then take out the virtual table address, and then calculate the offset in jmp, this is the address of the real virtual table, and from the function name gets to the address is just here the transit jump location is 191140 this place. So the simple comparison of the virtual table address to achieve this function is also not reliable, replaced by other compilers will also have compatibility issues, so say this interface I can only say powerless.



Nsclassfromstring This function is relatively simple, in fact, many places will use similar functions. For example, we write a program, draw a line on the program, and then save to the file. If we want to open this file later, we have to save the class name and other characteristics of this line, and when we read it, we first create the object based on the class name, which is the function similar to this one. In fact, we just need to move our hands and feet in the structure above, in particular, to achieve:


 
1 typedef void * (* pFn) ();
  2 // Here we use the class name as the unique identifier, which is the szClassName variable
  3 // Then two linked lists are used to connect the entire inheritance relationship
  4 struct ClassRunTimeType
  5 {
  6 char * szClassName;
  7 static ClassRunTimeType * pFirstClass;
  8 ClassRunTimeType * m_pPrevClassRunTimeType;
  9 ClassRunTimeType * m_pNextClassRunTimeType;
10 pFn pfn;
11};


PFN This function is primarily used to create objects, and we only need to pass in a function pointer when assigning a value to the struct, and the purpose of the function is to create the object. First we need to traverse our list, find the corresponding class name, and then call this function to create the object. Instead, Nsstringfromclass can be implemented in a similar way, with reference to the sample code.



As for judging whether the same instance is very simple, first compare the address is right, the words are exactly the same ^_^ followed by a unique identity, the same is the same class object.



Dynamictype.zip






C + + simulation implements OBJECTIVE-C dynamic type


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.