C + + type conversion

Type conversion in C language

In C language, if the types of the left and right sides of the assignment operator are different, or the shape participating argument types do not match, or the return value type is inconsistent with the received return value type, type conversion is required. There are two forms of type conversion in C language: implicit type conversion and explicit type conversion.

  1. Implicit type conversion: the compiler automatically performs in the compilation stage. If it can be converted, it will be converted. If it cannot be converted, it will fail to compile
  2. Explicit type conversion: it needs to be handled by the user
int main()
{
	int i = 1;
	//Implicit type conversion -- similar types, and the meaning of type representation is similar
	double d = i;
	printf("%d,%.2f\n", i, d);

	int *p = &i;
	//Display forced type conversion -- different types and different meanings
	int address = (int)p;
	printf("%x %d\n", p, address);
	return 0;
}

Defect: the visibility of conversion is poor. All conversion forms are written in the same form, so it is difficult to track the wrong conversion

C + + cast

In order to enhance the visibility of type conversion (I think implicit type conversion and forced type conversion are not standardized), standard C + + introduces four named forced type conversion operators:

static_cast,reinterpret_cast,const_cast,dynamic_cast

Why does C + + need four types of conversion

The C style conversion format is very simple, but it has many disadvantages:

  • Implicit type conversion may cause problems in some cases: for example, loss of data precision
  • Explicit type conversion mixes everything together, and the code is not clear enough

Therefore, C + + puts forward its own type conversion style. Note that since C + + should be compatible with C language, the conversion style of C language can also be used in C + +.

static_cast

static_cast is used for non polymorphic type conversion (static conversion). Static can be used for any type conversion implicitly performed by the compiler_ Cast, but it cannot be used to convert two unrelated types

//1,static_cast similar type
int main()
{
	double d = 12.34;
	int a = static_cast<int>(d);
	cout << a << endl;

	//no way
	//	int *p = &i;
	//	int address = static_cast<int>(p);
	return 0;
}

reinterpret_cast

reinterpret_ The cast operator usually provides a lower level reinterpretation of the bit pattern of the operand, which is used to convert one type to another

//2,reinterpret_cast -- conversion of unrelated types
int main()
{
		int i = 5;
		int *p = &i;
		int address = reinterpret_cast<int>(p);
		cout << address << endl;
		return 0;
}

const_cast

const_ The most common use of cast is to delete the const attribute of variables to facilitate assignment

//const_cast -- remove const attribute during conversion
int main()
{
		const int a = 2;
		//int* p = (int*)&a; // const int*
		int* p = const_cast<int*>(&a); // const int*
		*p = 3;
	
		cout << a << endl;
		cout << *p << endl;
	return 0;
}

dynamic_cast

dynamic_cast is used to convert the pointer / reference of a parent object to the pointer or reference of a child object (dynamic conversion)

Upward Transformation: subclass object pointer / reference - > parent class pointer / reference (no conversion required, assignment compatible rules)


Downward Transformation: parent object pointer / reference - > subclass pointer / reference (dynamic_cast transformation is safe)

class A
{
public:
	virtual void f(){}

	int _a;
};

class B : public A
{
public:
	int _b;
};

// Pointer to parent class A, turn a into a pointer to child class B -- turn down
void fun(A* pa)
{
	
	B* pb1 = (B*)pa;//Strong rotation, unsafe
	//If pa points to a subclass object, it can be transferred, but if pa points to a parent object, it cannot be transferred
	//pb1->_b = 10;

	// dynamic_cast will first check whether the conversion is successful. If it is successful, the conversion will be successful. If not, nullptr will be returned
	B* pb2 = dynamic_cast<B*>(pa); // safe
	if (pb2)
	{
		pb1->_b = 10;
	}

	cout << "pb1:" << pb1 << endl;
	cout << "pb2:" << pb2 << endl;
}

int main()
{
	A a;
	B b;
	fun(&a);
	fun(&b);

	return 0;
}

be careful:

  • dynamic_cast can only be used for classes with virtual functions
  • dynamic_cast will first check whether the conversion is successful. If it is successful, the conversion will be successful, and if not, 0 will be returned

Note: casts close or suspend normal type checking. Before using casts every time, programmers should carefully consider whether there are other different methods to achieve the same purpose. If non casts are not possible, the field of use of casts should be limited to reduce errors
Opportunities.

It is strongly recommended to avoid casting

explicit

explicit keyword prevents implicit conversions through the conversion constructor

RTTI

RTTI: short for Run-time Type identification, that is, Run-time Type identification.
C + + supports RTTI in the following ways:

  • typeid operator
  • dynamic_cast operator
  • decltype: you can declare, pass parameters or use
int main()
{
	string s;
	cout << typeid(s).name() << endl;
	decltype(s);
	auto f = [](void* ptr){free(ptr); };
	decltype(f) func;
	return 0;
}

Keywords: C++

Added by XeNoMoRpH1030 on Wed, 02 Mar 2022 07:08:39 +0200