#include <iostream>
#include <vector>
/**
转型操作符static_cast, const_cast,dynamic_cast,reinterpret_cast
*/
// static_cast
void Test1()
{
// C语言转型:(type)expression;
double a = 10.5;
int b = 20;
int c = (int)a;
double d = (double)b;
/* c++ static_cast与c类型转换有相同的功能,都有不能将struct->int, double->pointer
旧式的C语言转型一样有这些限制,static_cast不能移除表达式的const常量属性,const_cast专司此职
*/
// static_cast<type>(expression)
int sc = static_cast<int>(a);
}
// const_cast
class Base
{
virtual void Test(){};
};
class Derived : public Base
{
void Test()
{
std::cout << "overwrite" << std::endl;
}
};
void Update(Derived *pd)
{
std::cout << "pd ptr:" << pd << std::endl;
}
void UpdateRefer(Derived &pd)
{
std::cout << "pd ptr:" << &pd << std::endl;
}
void Test2()
{
Derived d;
const Derived &crd = d;
// Update(&crd); // error, invalid conversion from 'const Derived*' to 'Derived*'
Update(const_cast<Derived *>(&crd)); // ok, const_cast去掉const属性,并crd再函数中能够被更改
// c类型转换
Update((Derived *)&crd); // 使用c类型转换也达到同样效果
Base *pb = new Derived();
// Update(pb); // error, invalid conversion from 'Base*' to 'Derived*, 不能从上到下转换
// Update(const_cast<Derived*>(pb)); // error, const_cast不能进行继承体系的向下转型
}
// dynamic_cast:用来执行将继承体系安全的向下进行转型(将base指针或引用转换为derived指针或引用),转型失败返回null
void Test3()
{
// 运行时 dynamic_cast 的操作数必须包含多态类类型,基类类型向下转换时,需要有虚函数,否则会报错
Base *pb = new Base();
Update(dynamic_cast<Derived *>(pb)); // 传给update函数指针,pb指向Derived,若真的有指向Derived的东西,否则传过去是空指针
try
{
UpdateRefer(dynamic_cast<Derived &>(*pb)); // 传给udpate函数引用,pd指向Derived,若真的有指向Derived的东西,否则抛出std::bad_cast异常
}
catch (std::exception e)
{
std::cout << e.what() << std::endl;
}
// dynamic_cast只能用在继承体系中,无法用在缺乏虚函数的类型上,也不能去除常量属性
//若想转换一个不涉及有继承机制的类型转换,使用static_cast,若想去掉const属性必须使用const_cast(唯一)
int a =10;
double b = 20.5;
// dynamic_cast<int*>(&b); error,未涉及继承机制多态
// dynamic_cast<double>(a);error,未涉及继承机制多态
Derived rd;
const Derived& crd = rd;
// Update(dynamic_cast<Derived*>(&crd)); error,不能用于去除const属性
}
// reinterpret_cast函数指针类型转换
using funcType = void(*)();
int print()
{
return 0;
}
void Test4()
{
funcType funcArray[10]; // 定义函数指针数组
// funcArray[0] = print; error, print函数返回类型为int,而元素是一个void返回类型函数指针,不匹配
// 解决方式是使用reinterpret_cast,但不可移植,非必要不要使用,结果可能无法预料
funcArray[0] = reinterpret_cast<funcType>(print);
// 可以将整数转换为地址,即任意类型转换,不需要考虑类型收窄和安全性
int a = 0x61;
char* p =reinterpret_cast<char*>(&a);
std::cout<<"p:"<<p<<std::endl;
//char *b = static_cast<char*>(&a);// error,non-convertable int* to char*
}
int main()
{
Test3();
return 0;
}
C++ 四大类型转换操作符
于 2022-04-23 22:53:05 首次发布