In object-oriented programming, sometimes we need to query whether an object can be used as a certain type of polymorphism at runtime. Similar to the instanceof of Java and the as and is operators of C #, C ++ provides the dynamic_cast function for dynamic transformation. Compared with C-style forced type conversion and C ++ reinterpret_cast, dynamic_cast provides a type security check, which is a conversion based on Capability Query, therefore, dynamic_cast is more recommended for converting between Polymorphism types. This article describes the significance, usage, and precautions of dynamic_cast.
Basic usage
Dynamic_cast can get the reference or pointer of the target object:
T1 obj;
T2 * pObj = dynamic_cast <T2 *> (& obj); // convert to the T2 pointer. If the pointer fails, NULL is returned.
T2 & refObj = dynamic_cast <T2 &> (obj); // convert it to T2 reference. If it fails, a bad_cast exception is thrown.
Polymorphism type
Note: The Type T1 of the object to be converted must be a polymorphism type, that is, T1 must inherit from other classes in public or T1 has virtual functions (inherited or custom ). If T1. The following example shows which classes belong to the polymorphism type and which classes are not:
// A is non-polymorphism type
Class {
};
// B is a Polymorphism
Class B {
Public: virtual ~ B (){}
};
// D is a Polymorphism
Class D: public {
};
// E is non-polymorphism type
Class E: private {
};
// F is a Polymorphism
Class F: private B {
}
Horizontal Transformation
There are three types of conversions between Polymorphism types:
1. Up Cast)
2. Down Cast)
3. Cross Cast)
Upward transformation is the basis of polymorphism. You only need to assign the sub-class pointer or reference to the base class pointer or reference without using any special method. Of course, dynamic_cast also supports upward transformation, and it is always successful. In terms of downward transformation and horizontal transformation, dynamic_cast has no difference, and they all belong to capability query. For ease of understanding, consider dynamic_cast as cross cast:
Class Shape {
Public: virtual ~ Shape ();
Virtual void draw () const = 0;
};
Class Rollable {
Public: virtual ~ Rollable ();
Virtual void roll () = 0;
};
Class Circle: public Shape, public Rollable {
Void draw () const;
Void roll ();
};
Class Square: public Shape {
Void draw () const;
};
// Horizontal transformation failed
Shape * pShape1 = new Square ();
Rollable * pRollable1 = dynamic_cast <Rollable *> (pShape2); // pRollable is NULL
// Horizontal transformation successful
Shape * pShape2 = new Circle ();
Rollable * pRollable2 = dynamic_cast <Rollable *> (pShape2); // pRollable is not NULL
Pointer comparison
In the following example, the values of pShape2 and pRollable2 on my machine are:
PShape2: 0x0039A294, pRollable2: 0x0039A290
It indicates that dynamic_cast sets different offsets for different polymorphism types during transformation. The following question is:
PRollable2 = pShape2
What should this expression return? The answer is: 1, that is, the pointer is equal. You may be confused when you switch from C to C ++, because in C, pointer comparison is only a comparison of values. Obviously, for the polymorphism type, the C ++ compiler has done more behind-the-scenes work for the = Operator to ensure that the pointer is more focused on Object Identity rather than the pointer value. The Implementation Details involve the C ++ object model, which is not very familiar to me, so this article will not go into depth.
Reference
C ++ Common Knowledge Item27, 28
C ++ Typecasting
If you have any mistakes or deficiencies in this article, you are welcome to criticize and correct them!