【C++】四种强制类型转换

C++中有四种强制类型转换: 静态转换:static_cast、动态转换:dynamic_cast、重新解释:reinterpret_cast、常量转换(去常性):const_cast

1.静态转换(static_cast):可以用于基本数据类型之间的转换,也可以将基类指针或引用转换为派生类指针或引用,但是转换时需要保证类型转换是安全的。静态转换不能用于去除对象的const、volatile属性

2.动态转换(dynamic_cast):主要用于将基类指针或引用转换为派生类指针引用,但是转换时需要判断类型转换是否安全,如果不安全则返回空指针。只有指向具有多态性质的类的基类指针或引用才能使用dynamic_cast。

3.重新解释转换(reinterpret_cast):将一个指针或引用转换为一个与其类型无关的指针或引用。这种转换不会进行类型检查,因此很容易引发未定义的行为,应该避免使用。

4.常量转换(const_cast):用于去除一个变量或指针的const、volatile属性。这种转换也需要谨慎使用,因为去除const属性可能会导致未定义的行为。


 static_cast

static_cast<目的类型>(表达式)

1.基本数据类型之间的转换

{
	int a = 5;
	float b = 2.2;
	//printf("%f\n", a);//错误输出
	//printf("%d\n", b);//错误输出
	printf("%f\n", (float)a);
	printf("%d\n", (int)b);
	
	a = static_cast(b);//c++的强转
}

2.枚举类型之间的转换

int main()
{
	enum AA{A = 3,B = 10};
	enum BB{C = 5,D = 30};
	int a = 20;
	enum AA aa = A;
	cout << aa << endl;
	//aa = a;//枚举类型的只能用枚举类型内的赋值
	aa = static_cast(a);
	cout << aa << endl;

	enum BB bb = C;
	aa = static_cast(bb);
}

3.指针类型转换成void*

int main()
{
	int a = 10;
	int* p = nullptr;
	char ch = 'a';
	void* vp = &a;
	p = static_cast(vp);
	cout << *p << endl;

	//不安全--两边解析的大小不同
	vp = &ch;
	p = static_cast(vp);
	cout << *p << endl;
}

4.将一个变量转换成常量

        这种不用强转其实也可以

int main()
{
	int a = 20;
	const int ca = a;
	const int cb = static_cast(a);
	cout << ca << endl;
}

5.基类和派生类之间的转换--没有virtual

class A
{
public:
	void fn() { cout << "A::fn" << endl; }
	void gn() { cout << "A::gn" << endl; }
};
class B :public A
{
public:
	void fn() { cout << "B::fn" << endl; }//隐藏,没有虚
	void hn() { cout << "B::hn" << endl; }
};
int main()
{
	A a;
	B b;
	A* pa = &b;
	pa->fn();//A
	pa->gn();//A
//	B* pb = &a;//error
	B* pb = static_cast(&a);
	pb->fn();//B
	pb->gn();//A
	pb->hn();//B
	pb->A::fn();//A
}

6.没有关系的类之间的转换

class A
{
public:
	void fn() { cout << "A::fn" << endl; }
};
class B
{
public:
	B(A&a){}//构造函数可以进行强转
	void gn() { cout << "B::gn" << endl; }
};
int main()
{
	A a;
	B b = static_cast(a);//B b(a);
	b.gn();
}

dynamic_cast

        将基类的指针或引用安全的转换为派生类的指针或引用,并用派生类的指针或引用来调用非虚函数。
注意:当使用dynamic_cast时,该类型要包含有虚函数,才能进行转换,否则错误。

class A
{
public:
	void print() { cout << "A::print" << endl; }
	virtual ~A() {};//多态
};
class B :public A
{
public:
	void show() 
	{
		cout << "B::show" << endl;
	}
};
int main()
{
	A* pa = new A;
	B* pb = dynamic_cast(pa);
	pb->print();
	pb->show();
}

reinterpret_cast

        适用于指针转换为另一种指针,转化不用修改指针变量值数据存储格式,不改变指针变量的值,只需要在编译时重新解释指针的类型即可。也可以将指针,直接转化成整形值。

int main1()
{
	float ff = 3.5f;
	float* pf = &ff;
	int* pi = reinterpret_cast(pf);//编译时重新解释
	cout << *pi << endl;//取不到正确的值
	cout << *pf << endl;//pf不变

	//整形按二进制补码存
	unsigned int a = -2;//把-2放到a开辟的空间中
	/*
	00000000 00000000 00000000 00000010
	11111111 11111111 11111111 11111110:-2,4294967294
	unsigned无符号位
	*/
	//浮点sem存
}

class A
{

};
class B
{

};
int main()
{
	A* pa = new A;
	B* pb = reinterpret_cast(pa);
	//B*pb = (B*)pa;
	int a = 10;
	int* pi = &a;
	long j = reinterpret_cast(pi);
	cout << j << endl;//地址值
}

const_cast

static_cast不能移除变量的const属性,const_cast可以,但是就算可以强转了const在数据区的内容也不改变。

int main()
{
    const int cb = 10;
    //int* p = &cb;
    //int* p = static_cast(&cb);//error
    int* p = const_cast(&cb);//
    *p = 30;
    cout << cb << endl;//cb在字符串常量区,改不了,输出10
}

你可能感兴趣的:(C++,c++,开发语言)