大多数语言里都有类型转换,C++里有
- const_cast
- reinterpret_cast
- dynamic_cast
- static_cast
等好几种转换
1.const_cast转换
一般来讲c++里使用c语言风格的强转是使用()的方式来实现强转,但是如果转换失败就会出现野指针,只能逐行代码检查了
为了安全c++里有const_cast转换,转换失败会返回一个null
#include <iostream>
#include <string>
using namespace std;
//定义一个Graphic的类
class Graphic
{
private:
int points;
string shape;
public:
Graphic(int points, string shape);
//显示基本信息的方法
void PrintInfo();
};
void Graphic::PrintInfo()
{
//初始化
cout << "shape: " << shape << endl;
}
Graphic::Graphic(int points, string shape)
{
this->points = points;
this->shape = shape;
}
//----上面就是一个普通的类----
int main()
{
//被const函数修饰的函数,这个函数里的所有数据都不能被修改,只能访问
//const Graphic* graphic = new Graphic(3,"***形");
cout << "c++风格转换" << endl;
const Graphic* graphic = new Graphic(3,"***形");
Graphic* gra = const_cast<Graphic*>(graphic);
//const_cast 把const修饰的类型转换为非const类型,
//注意: gra还是指向原来的对象graphic
gra->PrintInfo();
cout << "c语言风格转换" << endl;
//c语言风格是强转是使用(),是万能强转,但是不安全。
//若转换失败就产生野指针,只能逐行代码检查了。
Graphic* newGraphic = (Graphic*)graphic;//C语言风格的抢转
newGraphic->PrintInfo();
delete graphic;
return 0;
}
结果如下图所示:
2.reinterpret_cast 再次中间转换
还是上面的那个类,先将Graphic转换为int类型,然后将int类型转换为Graphic类型
具体代码如下:
#include <iostream>
#include <string>
using namespace std;
//reinterpret_const 再次中间转换
class Graphic
{
private:
int points;
string shape;
public:
Graphic(int points, string shape);
void PrintInfo();
};
void Graphic::PrintInfo()
{
//初始化
cout << "shape: " << shape << endl;
}
Graphic::Graphic(int points, string shape)
{
this->points = points;
this->shape = shape;
}
int main()
{
const Graphic* graphic = new Graphic(3, "***形");
//reinterpret_cast是无关类型转换的,可以转换为其他类型,int bool ....
//要使用的话就需要再转一次
cout << "reinterpret_cast转换" << endl;
//将Graphic*类型转换为int类型,用test变量来接收
int test = reinterpret_cast<int>(graphic);
//将int类型的test转换回去为Graphic*类型
Graphic* newTest = reinterpret_cast<Graphic*>(test);
//调用PrintfInfo()函数
newTest->PrintInfo();
delete graphic;
return 0;
}
结果如图所示:
3.Dynamic_cast 转换和Static_cast转换
说明:
Graphic是基类,
Circle继承Graphic,
Ellipse继承Circle类。
#include <iostream>
#include <string>
using namespace std;
//dynamic_cast 和static_cast
class Graphic
{
public:
void GraphicShape()
{
cout << "Graphic 特有的函数" << endl;
}
virtual void PrintInfo() {}
virtual void PrintPoint() {}
};
//子类 circle
class Circle : public Graphic
{
private:
int points;
public:
void CircleShape();
};
void Circle::CircleShape()
{
cout << "Circle 特有的函数" << endl;
}
//椭圆继承圆
class Ellipse : public Circle
{
public:
void EllipseShape();
};
void Ellipse::EllipseShape()
{
cout << "椭圆特有的函数" << endl;
}
int main()
{
cout << "danamic_cast转换" << endl;
//danamic_cast动态转换,可以向上转换,也可以向下转换,也就是父类可以转换为子类,子类可以转换为父类,子父级转换
//向下转换:会进行类型检测,无法转换的时候会返回为null
//向下转换:Graphic转换为Circle
Graphic* graphic = new Circle();
Circle* circle = dynamic_cast<Circle*>(graphic);
circle->CircleShape();
//向上转换
Graphic* g = dynamic_cast<Circle*>(circle);
g->GraphicShape();
//隐式转换
g = circle;
g->GraphicShape();
//向下转换
//Graphic直接转换为Ellipse类 略过中间的Circle类
Graphic* graphic2 = new Ellipse();
Ellipse* ellipse = dynamic_cast<Ellipse*>(graphic2);
//Ellipse* ellipse =(Ellipse*)graphic;
ellipse->EllipseShape();
cout << "static_cast 转换" << endl;
//static_cast 也需要虚函数
//无法转换const修饰的类
//无法转换_unaligned修饰的类(对齐)
Ellipse* ellipse2 = static_cast<Ellipse*>(graphic2);
ellipse2->EllipseShape();
delete ellipse2;
delete graphic;
return 0;
}
结果如图所示:
结果分析:
第二行: Circle特有的函数 是向下转换,Graphic–>Circle类调用Circle特有的函数,表明使用dynamic_cast向下转换成功
第三行: Graphic特有的函数 是向上转换,Circle–>Graphic类,调用Graphic特有的哈数,表明使用dynameic_cast向上转换成功
第四行:Graphic特有的函数 是隐式转换
第五行:椭圆特有的函数 是向下转换,Graphic–>Ellipse 父类直接转换到孙类
第七行:椭圆特有的函数 是向下转换Graphic–>Ellipse 父类直接转换到孙类,但是是通过static_cast转换方式转换的。