C++中四种cast的用法及区别

 一、直接代码运行看结果

test01到test04(),挨个运行即可看出差别,有的注释打开后观察报错信息。

/*======================================================
*
*程序说明:	4种cast的使用
*运行平台:	Linux/Windows
*创建日期:	20190827
*作	  者:	LiuHuan
*
*======================================================*/

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;

class Building{};
class Animal{};
class Cat :public Animal{};

// 1、static_cast
void test01()
{
	int a = 97;
	int b = 98;
	char c = static_cast<char>(a);
	char d = b;
	cout << "C: " << c << ", d: " << d << endl;	// C: a, d: b

	// 基础数据类型指针不能转
	/*int* p = NULL;
	char* sp = static_cast<char*>(p);*/

	// 对象指针 也不能转
	/*Building* building = NULL;
	Animal* animal = static_cast<Animal*>(building);*/

	// 转换具有继承关系的对象指针
	// 父转子	-> OK
	Animal* animal = NULL;
	Cat* cat = static_cast<Cat*>(animal);

	// 子转父 -> OK
	Cat* cat1 = NULL;
	Animal* animal1 = static_cast<Animal*>(cat1);

	// 转换具有继承关系的引用
	// 父转子
	Animal animalobj;
	Animal& aniref = animalobj;
	Cat& catref = static_cast<Cat&>(animalobj);	// OK
	// Cat& catref = static_cast<Cat&>(aniref);  // OK

	// 子转父
	Cat catobj;
	Cat& catref1 = catobj;
	Animal& animalref1 = static_cast<Animal&>(catref1);	// OK
	//Animal& animalref1 = static_cast<Animal&>(catobj);	// OK

	// 结论:static_cast用于内置的数据类型
	// 或者具有继承关系的指针或引用
}

// 2、dynamic_cast转换具有继承关系的指针或引用,在转换前进行对象类型检查
void test02()
{
	// 基础数据类型	-> 不可以
	/*int a = 10;
	char c = dynamic_cast<char>(a);*/

	// 非继承关系的指针	-> 不可以
	/*Animal* ani = NULL;
	Building* building = dynamic_cast<Building*>(ani);*/

	// 具有继承关系指针
	// 父类转子类   小->大 不安全,类型检查不通过
	/*Animal* ani = NULL;
	Cat* cat = dynamic_cast<Cat*>(ani);*/

	// 子类转父类指针(大到小),类型安全
	Cat* cat = NULL;
	Animal* ani = dynamic_cast<Animal*>(cat);

	// 结论:dynamic_cast只能转换具有继承关系的指针或引用
	// 而且只能由子类转为父类
}

// 3、const_cast 指针、引用或对象指针
void test03()
{
	// 1、基础类型
	int a = 10;
	const int& b = a;
	int& c = const_cast<int&>(b);
	c = 20;

	cout << "a: " << a << ", b: " << b << ", c: " << c << endl;	// a: 20, b: 20, c: 20

	// 2、看指针	
	const int* p = NULL;
	int* p2 = const_cast<int*>(p);

	int* p3 = NULL;
	const int* p4 = const_cast<const int*>(p3);
	// 结论:增加或去除变量的const属性
}

// 4、reinterpret_cast 强制转换所有类型
typedef void(*FUNC1)(int, int);
typedef int(*FUNC2)(int, char*);
void test04()
{
	// 1、无关的指针类型都可以进行转换
	Building* building = NULL;
	Animal* ani = reinterpret_cast<Animal*>(building);

	// 2、函数指针转换也可以
	FUNC1 func1 = NULL;
	FUNC2 func2 = reinterpret_cast<FUNC2>(func1);
}

int main()
{
	// test01();
	// test02();
	// test03();
	test04();
	// system("pause");  // Windows下去掉注释, linux下需要注释
	return 0;
}

二、总结

C++各cast类型转换
static_cast基础类型(基础类型指针不行)和具有继承关系的类对象指针/引用互转。
dynamic_cast只能转换具有继承关系指针或引用,且只能由子类转为父类(类型安全)
const_cast增加或去除变量的const属性
reinterpret_cast强制转换所有类型

 关注点:

1、清楚地知道要转变的变量,转换前是什么类型,转换后是什么类型,以及转换后有什么后果。

2、一般情况下,不建议类型转换,避免进行类型转换。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

幻欢子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值