[C/C + + basics] (type conversion Series II) static_cast and traditional C Style Cast

Keywords: C++

conclusion

  1. In C + + code, try to use static for basic types (int, float, void, enum, pointer, etc.)_ Cast instead of C-style cast.
  2. 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

  1. The conversion between basic data types, such as char, int, float, double, etc., needs to ensure its own security.
  2. Converts a void pointer to a pointer of any type.
  3. Convert any type to void type.
  4. 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!

Posted by art15 on Wed, 06 Oct 2021 17:11:36 -0700