Type recognition is divided into two types: one is recognition by compile-time type and one is runtime type recognition ;
compile-time type recognition:static_cast;
Runtime type recognition (RTTI), C + + provides RTTI through the following operators;
1) Thedynamic_cast operator, which converts a pointer or reference of a base class type safely to a pointer or reference of a derived type;
2)typeid operator, returns the actual type of the pointer or reference to the object being referred to.
a class with at least one virtual function . For other types, returns information for static (that is, compile-time) types.
For the convenience of the narrative, we first write the code of the class used, where animal is the base class, and the Cat and dog classes are derived classes;
1 classAnimal2 {3 Public:4 Virtual~Animal () {}5 Virtual voidRun ()6{cout<<"Test"<<Endl;}7 };8 9 classCat: PublicAnimalTen { One Public: A voidRun () -{cout <<"Cat ..."<<Endl; } - }; the - classDog: PublicAnimal - { - Public: + voidRun () -{cout <<"Dog."<<Endl;} +};
The example code for static_cast (static type conversion) is as follows:
1 //static_cast occurs during compilation2#include <iostream>3#include <string>4#include <vector>5 using namespacestd;6 7 intMainintargcConst Char*argv[])8 {9Animal *Base;Ten Cat C; One Dog D; A Base= &C; - -Cat *pc = static_cast<cat*> (Base); thePc->run ();//Cat ... - -Dog *PD = static_cast<dog*> (Base); -Pd->run ();//Cat.. Print a Cat object that is actually pointing to + return 0; -}
Note:static_cast occurs during the compilation period , if the conversion fails, a compile error is generated, and if the compilation succeeds, the conversion succeeds. But static_cast still has a certain risk, especially when the downward shape . When you convert a base* (base-class pointer) to a deriverd* (derived class pointer), the pointer can be converted, but the pointer does not necessarily point to the derived object.
The sample code for dynamic_cast (dynamic run conversion) is as follows:
To convert a reference:
//Convert ReferenceintMainintargcConst Char*argv[]) {Cat C; Dog D; Animal&Base= C;//must be initialized when referencingCat&PC = dynamic_cast<cat&> (Base); cout<< &pc <<Endl; //Test_result 0xbfebb0Dog &PD = dynamic_cast<dog&> (Base); cout<< &PD <<Endl; //Test_result Bad_cast is different from the pointer return 0;}
Conversion pointers:
//Convert pointer
intMainintargcConst Char*argv[]) {Cat C; Dog D; Animal*Base= &C; Cat*PC = dynamic_cast<cat*> (Base); cout<< pc << Endl;//Print the address of the pointer//Test_result oxbf94b98cDog *PD = dynamic_cast<dog*> (Base); cout<< PD <<Endl; //Test_result 0//Conversion not successful return 0;}
Note: The pointer used with dynamic_cast must be valid- it must be null, or point to an object
Specific implementations of dynamic_cast:
1. dynamic_cast involves run-time type checking. Dynamic_cast fails if the object bound to the reference or pointer is not an object of the target type;
A) if the dynamic_cast to the pointer type fails, the result of the dynamic_cast is 0;
b) If dynamic_cast fails to convert to a reference type, an exception of type Bad_cast is thrown .
steps : The dynamic_cast operator performs two operationsat a time,1: First verifies that the requested conversion is valid, and2, in the case where the conversion is valid, The operation characters is actually converted.
C++primer 4th gives the standard practice of using the dynamic_cast operator.
// pointer condition, if (Derived *derivedptr = dynamic_cast<derived*>(baseptr) { // conversion succeeded } else{ // failure handling }
Citation:
// Citation Situation Try { const Derived &d = dynamic_cast<const derived&>(b); // Success Situation } catch(bad_cast) { // failure handling }
The logic of this piece of code is very strict:
The scope of the Derived *derivedptr exists only in the IF statement
It is not possible to insert code between dynamic_cast and test conversion results, so it is not possible to use derivedptr before the test conversion succeeds.
Third, typeid runtime type conversion;
The mechanism of action of typeid is similar to dynamic_cast. The sample code is as follows:
1 intMainintargcConst Char*argv[])2 {3 Cat C;4 Dog D;5cout << typeID (string). Name () <<Endl;6 //type name7cout << typeID (c). Name () << Endl;//3Cat8cout << typeid (d). Name () << Endl;//3Dog9 Animal A;Tencout << typeID (a). Name () << Endl;//6Animal OneAnimal *pa = &C; Acout << typeid (*PA). Name () << Endl;//3Cat - - return 0; the}
Dynamic type information is returned only if the operand of typeid satisfies the following two conditions,a) with a virtual function; b) is an object of class type. In addition, the test pointer (relative to the object pointed to by the pointer) returns the static, compile-time type of the pointer.
Example of Rtti: use of C + + Rtti
Rtti of special tools and technologies for C + +