RTTI in C ++)

Source: Internet
Author: User

 

1. dynamic_cast Operator
Converts a pointer or reference of the base class type to a pointer or reference of the derived class type safely.

Note: The base class must have at least one virtual function, so that the source type may be polymorphism to determine the type at runtime. Otherwise, compilation errors may occur.

If the conversion is successful, a pointer or reference pointing to the converted type is returned. If the conversion fails, the Conversion Result of the pointer type is 0. If the conversion fails, a bad_cast type exception is thrown.

For pointer type, the operand can be 0. But there is no null type reference.

Test code:


[Cpp]
# Include <iostream>
# Include <typeinfo>
 
Using namespace std;
Class B
{
Public:
Virtual void f ()
{
Cout <"B: f" <endl;
}
Void ff ()
{
Cout <"B: ff" <endl;
}
};
 
Class D: public B
{
Public:
Void f ()
{
Cout <"D: f" <endl;
}
Void g ()
{
Cout <"D: g" <endl;
}
};
 
 
Void ta ()
{// Pointer
B * B = 0;
D * d = 0;
B = new D ();
B-> f (); // D: f
D = dynamic_cast <D *> (B );
If (d)
{D-> g ();} // D: g
Else
{B-> ff ();}
 
B = new B ();
D = dynamic_cast <D *> (B );
If (d)
{D-> g ();}
Else
{B-> ff ();} // B: ff
 
}
 
Void tb ()
{
D;
B c;
B & B = d;
Try
{
D & dt = dynamic_cast <D &> (B );
Dt. g ();
}
Catch (bad_cast)
{
Cout <"dynamic cast failed" <endl;
}
B & br = c; // It will be strange if B = c is written here.
Try
{
D & dt = dynamic_cast <D &> (br );
Dt. g ();
}
Catch (bad_cast)
{
Cout <"dynamic cast failed" <endl;
}
}
 
Int main ()
{
Ta ();
Cout <"-------" <endl;
Tb ();
Return 0;
}

# Include <iostream>
# Include <typeinfo>

Using namespace std;
Class B
{
Public:
Virtual void f ()
{
Cout <"B: f" <endl;
}
Void ff ()
{
Cout <"B: ff" <endl;
}
};

Class D: public B
{
Public:
Void f ()
{
Cout <"D: f" <endl;
}
Void g ()
{
Cout <"D: g" <endl;
}
};


Void ta ()
{// Pointer
B * B = 0;
D * d = 0;
B = new D ();
B-> f (); // D: f
D = dynamic_cast <D *> (B );
If (d)
{D-> g ();} // D: g
Else
{B-> ff ();}

B = new B ();
D = dynamic_cast <D *> (B );
If (d)
{D-> g ();}
Else
{B-> ff ();} // B: ff

}

Void tb ()
{
D;
B c;
B & B = d;
Try
{
D & dt = dynamic_cast <D &> (B );
Dt. g ();
}
Catch (bad_cast)
{
Cout <"dynamic cast failed" <endl;
}
B & br = c; // It will be strange if B = c is written here.
Try
{
D & dt = dynamic_cast <D &> (br );
Dt. g ();
}
Catch (bad_cast)
{
Cout <"dynamic cast failed" <endl;
}
}

Int main ()
{
Ta ();
Cout <"-------" <endl;
Tb ();
Return 0;
}

 

Running result:


[Cpp]
D: f
D: g
B: ff
-------
D: g
Dynamic cast failed

D: f
D: g
B: ff
-------
D: g
Dynamic cast failed

 


2. typeid Operator
Expression of typeid:

Typeid (e)

E can be any expression or type name.

If the expression type is a class type and the class contains at least one virtual function, the dynamic type (actual type) of the expression may be different from its static type.

If the operand is not of the class type or does not have a virtual function, the typeid operator specifies the static type of the operand. If the operand defines at least one virtual function, the computing type is calculated at runtime.

The iso c ++ standard does not have the exact definition of type_info. The exact definition of type_info is related to the compiler, but the standard specifies that the implementation must provide the following four operations:


T1 = t2 if the t1 and t2 objects are of the same type, true is returned; otherwise, false is returned.
T1! = T2 true is returned if the t1 and t2 objects are of different types; otherwise, false is returned.
T. name () returns the C-style string of the type. The type name is generated by system-related methods.
T1.before (t2) returns the bool value indicating whether t1 exists before t2

 

The type_info class provides public virtual destructor so that users can use it as the base class. Its default constructor, copy constructor, and value assignment operator are both defined as private. Therefore, objects of the type_info type cannot be defined or copied. The only way to create a type_info object in the program is to use the typeid operator (it can be seen that if typeid is treated as a function, it should be the friend of type_info ). The name member function of type_info returns the C-style string to indicate the corresponding type name, however, it is important to note that the returned type name is not necessarily consistent with the corresponding type name used in the Program (this is often the case, see the program below), which is determined by the implementation of the compiler, the standard only requires that a unique string be returned for each type.


Test code:

 

 

[Cpp]
# Include <iostream>
# Include <typeinfo>
 
Using namespace std;
Class B
{
Public:
Virtual void f ()
{
Cout <"B: f" <endl;
}
Void ff ()
{
Cout <"B: ff" <endl;
}
};
 
Class D: public B
{
Public:
Void f ()
{
Cout <"D: f" <endl;
}
Void g ()
{
Cout <"D: g" <endl;
}
};
 
Void tc ()
{
D;
B B;
Int k = 0;
Cout <typeid (k). name () <"," <typeid (int). name () <endl;
Cout <typeid (float). name () <endl;
Cout <typeid (B). name () <endl;
Cout <typeid (d). name () <endl;
 
B * bp = new D ();
Cout <"prt:" <typeid (bp). name () <endl; // you can directly judge the pointer instead of the type of the object to which the Pointer Points.
Cout <typeid (* bp). name () <endl;
Bp = new B ();
Cout <typeid (* bp). name () <endl;
Cout <typeid (* bp). before (typeid (char) <endl;
Cout <typeid (char). before (typeid (* bp) <endl;
Cout <typeid (B). before (typeid (D) <endl;
}
Int main ()
{
Tc ();
Return 0;
}

# Include <iostream>
# Include <typeinfo>

Using namespace std;
Class B
{
Public:
Virtual void f ()
{
Cout <"B: f" <endl;
}
Void ff ()
{
Cout <"B: ff" <endl;
}
};

Class D: public B
{
Public:
Void f ()
{
Cout <"D: f" <endl;
}
Void g ()
{
Cout <"D: g" <endl;
}
};

Void tc ()
{
D;
B B;
Int k = 0;
Cout <typeid (k). name () <"," <typeid (int). name () <endl;
Cout <typeid (float). name () <endl;
Cout <typeid (B). name () <endl;
Cout <typeid (d). name () <endl;

B * bp = new D ();
Cout <"prt:" <typeid (bp). name () <endl; // you can directly judge the pointer instead of the type of the object to which the Pointer Points.
Cout <typeid (* bp). name () <endl;
Bp = new B ();
Cout <typeid (* bp). name () <endl;
Cout <typeid (* bp). before (typeid (char) <endl;
Cout <typeid (char). before (typeid (* bp) <endl;
Cout <typeid (B). before (typeid (D) <endl;
}
Int main ()
{
Tc ();
Return 0;
}

Result:


[Cpp]
I, I
F
1B
1D
Prt: P1B
1D
1B
1
0
1

I, I
F
1B
1D
Prt: P1B
1D
1B
1
0
1
G ++ is used here, And vs may be different from this.

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.