conclusion
- In C + + code, try to use static for basic types (int, float, void, enum, pointer, etc.)_ Cast instead of C-style cast.
- For the conversion between inheritance classes, try not to use static_cast uses dynamic instead_ Cast because of lack of sufficient security.
static_cast
The usual forms of use are:
new_type b = static_cast < new_type > ( expression );
static_cast is similar to C-style cast, but it is more restrictive and relatively safer.
Difference from C-style cast
The main difference between the two is static_cast has the function of compile time check, and C-style type conversion does not. Therefore, the former can help you find errors during compilation, while the latter will produce errors during program operation. Understanding the difference between the two can make us better understand the use of static_ The benefits of cast.
static_cast will allow the compiler to check whether the pointer is compatible with the data type being pointed to, which allows the programmer to catch this incorrect pointer allocation during compilation.
Give a brief example to illustrate:
char c = 1; char *pc = &c; //C style type conversion int *pi = (int*)pc; *pi = 5; //Memory out of bounds allocation may lead to memory overwriting and crash during operation //static_cast type conversion int *pi_2 = static_cast<int*>(pc); //Compilation error, this operation is not allowed.
The reason has been explained in the code. If you insist on this conversion, you need to use reinterpret_cast carries out type conversion. You can see this article. Compiled type conversion
Main application scenarios
- The conversion between basic data types, such as char, int, float, double, etc., needs to ensure its own security.
- Converts a void pointer to a pointer of any type.
- Convert any type to void type.
- Conversion between enum class and numeric type.
Simple examples
In the following situation, let's discuss this problem. Lao Wang has a son Xiao Ming. Lao Wang has 10 yuan and is going to leave it to Xiao Ming to inherit.
Xiao Ming has 11 yuan, so Xiao Ming has 16 yuan in total;
#pragma once #include<iostream> //Father: Lao Wang class LaoWang { public: LaoWang() :m_LaoWangMoney(10) {} ~LaoWang() {} virtual void money() { std::cout << m_LaoWangMoney<< std::endl; } void laowang_money() { std::cout << m_LaoWangMoney<< std::endl; } int m_LaoWangMoney; }; //Son, Xiao Ming class XiaoMing:public LaoWang { public: XiaoMing() :m_XiaoMingMoney(11) {} ~XiaoMing() {} void money() override { std::cout << m_LaoWangMoney / 2 + m_XiaoMingMoney << std::endl; } void xiaoming_money() { std::cout << m_XiaoMingMoney<< std::endl; } private: int m_XiaoMingMoney; };
Transformation between base types
A simple example: Lao Wang bought fruit, which was worth 5.9 yuan. After Lao Wang bargained, the merchant agreed to erase the change.
LaoWang lao_wang(); float fruits = 5.9; lao_wang.m_LaoWangMoney -= static_cast<int>(fruits);
The conversion of basic types is consistent with the type conversion of C style.
Transformation between inherited classes
For example: Xiao Ming grew up and became Lao Wang No. 2, and inherited Lao Wang's money; But because he can't rejuvenate, Lao Wang can't become Xiaoming No. 2
LaoWang* lao_wang = new LaoWang(); XiaoMing* xiao_ming = new XiaoMing(); //Subclass to base class, correct! LaoWang* lao_wang_2 = static_cast<LaoWang*>(xiao_ming); lao_wang_2->laowang_money(); //Base class rotor class, access error memory! XiaoMing* xiao_ming_2 = static_cast<XiaoMing*>(lao_wang); xiao_ming_2->xiaoming_money();
In this example, the compiler will not report errors, and the program will not crash. The sub class to base class (Xiaoming to Laowang) is completely correct, but in the base class rotor class (Laowang to Xiaoming), the program runs normally, but the error memory will be accessed, which is a more difficult error to find. So it's very unsafe.
emphasize
In C + + code, try to use static_cast replaces C-style forced type conversion to improve program security.
Like collection and pay attention, killing bugs can't stop!