Open the door to see the mountain nonsense
First, conversion related to polymorphic types
1, Polymorphic_cast and Dynamic_CAST
Dynamic_cast can safely convert a pointer to a polymorphic object to a derived class pointer. However, when the Dynamic_cast conversion fails, the return is null, that is, the success of Dynamic_cast is determined in the running period, and is not as determined in the compile period like other C built-in Cast. In other words, if the return value is not detected after dynamic_cast, it is equal to a timing bomb.
Boost's Polymorphic_casta increases the detection of the return value on the basis of Dynamic_cast. If the conversion fails, it will throw std :: bad_cast.
2, polymorphic_download and dynamic_cast
But throwing an exception reduces the efficiency of the program, and Dynamic_Cast will query a Type_info structure to determine the correct type, so whether it is a space cost or time cost, it will greatly increase.
Polymorphic_downcast can reduce costs to the lowest, or even on the compile period. However, this conversion must be very careful.
// # Define ndebug
#include
Using namespace std;
Struct a {
Virtual ~ a () {}
}
Class B: Public a {};
Class C: public a {};
Int main () {
A * PA = New C;
B * PB = POLYMORPHIC_DOWNCAST (pa);
}
Note that the NDEBUG (or the compiler is modified) is not defined, so that the polymorphic_download is successful when debugging. Finally, when everything is OK, the NDEBUG will be defined (or turn off the compiler). In this final software, Polymorphic_Downcast ensures secure conversion and ensures low operating costs.
3, glimpse inside
Template
Inline target polymorphic_cast (source * x) {
Target TMP = Dynamic_cast
IF (TMP == 0) throw std :: bad_cast ();
Return TMP;
}
Polymorphic_cast is essentially a Dynamic_cast.
Come with Polymorphic_Downcast now
Template
Inline target polymorphic_downcast (source * x) {
Assert (Dynamic_cast
Return static_cast
}
You can see Assert in Polymorphic_Downcast. When in debug mode, Assert will play a very critical role. If Dynamic_cast is successful, STATIC_CAST will inevitably do not have problems. When everything is ready in debug mode, turn off the feature of Assert, you can guarantee that there will be no problem in static_castne. This reduces the operating cost.
Second, conversion with digital related
1, numeric_cast and static_cast and implicit conversion
Let's take a look at the number of STINTIC_CAST converted to the integer of the Double type. Double D = 10;
INT i = static_cast
For this conversion, you can't see any defects, but the only thing that can be sure is that Double is 8bytes, and int 4bytes, which also shows that the converted value is extremely incorrect. For example, try to change the value of D to 999999999, you will find that the value of the converted I become extremely deformed. Although such conversion is a failure of failure, it is not all converted from "big" type to "small" type, nor all the conversions from "small" type to "big" type. Qualified conversion.
Boost's Numeric_cast can help us solve such problems. For example, for the above, when D is 9999999999, the conversion must fail, and Numeric_Cast throws the exception object of the Boost :: Bad_Numeric_cast. In this way, the effectiveness of the conversion value can be guaranteed. Usage is seen.
Double D = 10;
INT I;
Try {
i = boost :: numeric_cast
}
Catch (boost :: bad_numeric_cast) {
Std :: cout << "The conversion failed" << std :: end1;
}
The use of Numeric_cast is required.
1. Source type and target type must be copied
2, source type and target type must be digital type. That is, True is defined by the specialization of std :: numeric_limits <> :: is_specialized
3, the source type must be converted to the target type by static_cast
2, glimpse the interior
How does Numeric_cast know how this digital conversion failed? Numeric_cast reasonably applies std :: numeric_limits <>, and std :: numeric_limits <> is Type_tratis with built-in digital type. Of course, you can also add your own digital abstraction type to std :: numeric_limits <> That's in the special version, so Numeric_Cast can make a custom type.
Template
Inline target numeric_cast (source arg) {
TypedEf Detail :: Fixed_Numeric_Limits
Typedef detail :: fixed_numeric_limits
IF
(arg <0 &&! result_traits :: is_soud) // Conditions
|| (arg_traits :: is_signed&& arg || Arg> Result_traits :: max ()) // Conditions three { Throw Bad_Numeric_cast (); } Return static_cast } // numeric_cast Condition 1: If the current value of the source type object is less than 0, and the target type is unsigned, the conversion failed. Conditions 2: If the source type object is a symbolic, and its current value is less than the minimum value accommodated by the target type, the conversion failed. Condition 3: If the current value of the source type object is greater than the maximum value of the target type, the conversion failed. If these three conditions are not satisfied, then you can use Static_cast to convert this digital type with static_cast. // (OK, continue)