Effective C + + Read notes _ clause 27 try to do less transformational action
1. The three forms of transformation can be divided into two main categories.
(1) Legacy transformation (Old-style casts)
(1.1) (T) expresstion
(1.2) T (expression)
(2) New transformation (C++-style casts)
(2.1) const_cast<t> (expression)
(2.2) dynamic_cast<t> (expression)
(2.3) reinterpret_cast<t> (expression)
(2.4) static_cast<t> (expression)
2. A detailed introduction to the new transformation
(2.1) const_cast<t> (expression)
is often used to remove the constants of an object. It is the only operator with this skill yo, bad.
(2.2) dynamic_cast<t> (expression)
It is used primarily to perform a "security down transition", which is used to determine whether an object belongs to a type in the inheritance system.
The only action that cannot be performed by legacy syntax is the only transformational action that can cost significant operational costs.
Many implementations of dynamic_cast perform fairly slowly, especially deep inheritance or multiple inheritance.
Why use the Dynamics_cast operator, and how to avoid it.
Using Dynamics_cast is because you want to perform the derived class action function on a class object that you believe to be derived, but you have only one "point to base" pointer or regerence on your hand,
You can only rely on them to deal with objects.
There are two types of solutions:
(1) Use the container and store a pointer directly to the derived class object
Like what:
1 classWindow {2 // ...3 };4 classSpecialwindow: PublicWindow {5 Public:6 voidBlink ();7 //...8 };9 Tentypedef std::vector<std::tr1::shared_ptr<window>>VPW; One VPW winptrs; A //... - for(Vpw::iterator iter = Winptrs.begin (); ITER! = Winptrs.end (); + +ITER) { - if(Specialwindow *PSW = Dynamic_cast<specialwindow *> (iter->Get())) { thePsw=>Blink; - } - } - //---> Changes as follows: +typedef std::vector<std::tr1::shared_ptr<specialwindow>>VPSW; - VPSW winptrs; + //... A for(Vpsw::iterator iter = Winptrs.begin (); ITER! = Winptrs.end (); + +ITER) { at(*iter)Blink (); -}
Disadvantage: Unable to store pointers in the same container memory "point to all possible various window derived classes".
(2) Processing "all possible various window derived classes" through the base class interface, which is to provide the virtual function in the base class , For example:
1 classWindow {2 // ...3 Virtual voidBlink ();4 };5 classSpecialwindow: PublicWindow {6 Public:7 Virtual voidBlink ();8 //...9 };Ten Onetypedef std::vector<std::tr1::shared_ptr<window>>VPW; A VPW winptrs; - //... - for(Vpw::iterator iter = Winptrs.begin (); ITER! = Winptrs.end (); + +ITER) { the(*iter)Blink (); -}
Also note: Do not appear "serial" dynamic_casts, such code is large and slow and the foundation is not stable, maintainability and scalability are poor.
(2.3) reinterpret_cast<t> (expression)
Intent to perform a low-level transformation, the actual action is related to the compiler. It also means that it is not portable.
(2.4) static_cast<t> (expression)
Forcing implicit conversions, especially reverse conversions, but not const-->non-const, is Const_cast's skill.
1 classWindow {2 Public:3 // ....4 Virtual voidonResize ()5 {6 //...7 }8 };9 Ten classSpecialwindow: PublicWindow { One Public: A Virtual voidonResize () { -Static_cast<window> (* This). OnResize (); - /* the Note: The current object enters a "disabled" state: Changes to its base class component are not implemented, - and the changes to the derived class composition are implemented. - */ - // .... + } - }; + A //---correction at classSpecialwindow: PublicWindow { - Public: - Virtual voidonResize () { - window::onresize (); - } -};
3. Remember that any type conversion (whether it is a display transformation through a transformation operation, or an implicit conversion done through a compiler) often really makes the compiler compile code that executes during the run.
Summarize:
If you can, try to avoid the transition, especially in the efficiency-focused code to avoid dynamic_casts. If you have a design that requires transformational action, try to develop an alternative design that doesn't need to be transformed.
If transformation is necessary, try to hide it behind a function. The client can then invoke the function without having to put the transformation into their own code.
Rather than using C++-style (new) transformation, don't use legacy transformations. The former is very easy to identify, but also a comparative necromancy.
In fact, after reading, feel a little change, and then look back to the title: as little as possible to do transformational action.
Statement: All the text in this article is derived from the effective C + +, I do just follow my own reading habits written records. If you can help, that would be great.
Effective C + + Read notes _ clause 27 try to do less transformational action