C++ static_cast与dynamic_cast的区别

dynamic_cast运算符,用于将基类的指针或引用安全地转换成派生类的指针或引用。

当我们将这两个运算符用于某种类型的指针或引用时,并且该类型含有虚函数,运算符将使用指针或引用所绑定对象的动态类型

类型转换名称和语法
c风格的强制类型转换(Type Cast)很简单,不管什么类型的转换统统是:
TYPE b = (TYPE)a

c++风格的类型转换提供了4中类型转换操作符来应对不同场合的应用
static_cast 静态类型转换。如int转化成char
reinterpret_cast 重新解释类型
dynamic_cast 命名上理解是动态类型转换,如子类和父类之间的多态类型转换
const_cast 字面上理解就是去const属性

		类型转换格式
			TYPE b = static_cast<TYPE> a

类型转换介绍
static_cast<>() 静态类型转换,编译时c++编译器会做类型检查
若不同类型之间,进行强制类型转换,reinterpret_cast<>() 进行重新编译
dynamic_cast<>() 动态类型转换,安全的基类和子类之间转换,运行时类型检查
const_cast<>() 去除变量的只读属性

三种使用形式

dynamic_cast<type*> (e) //e必须为指针
dynamic_cast<type&> (e) // e 必须为一个左值
dynamic_cast<type&&> (e) //e不能是左值

#include <iostream>

using namespace std;

class Tree
{

};

class Animal
{
public:
	virtual void cry()
	{
		
	}

};

class Dog:public Animal
{
public:
	Dog():Animal()
	{
		age = 0;
	}

	virtual void cry()
	{
		cout << "汪汪 " << endl;
	}

	void doHome()
	{
		cout << "看家" << endl;
	}

	void printAge()
	{
		cout << age << endl;
	}

private:
	int age;
};

class Cat :public Animal
{
public:
	virtual void cry()
	{
		cout << "喵喵 " << endl;
	}

	void doThing()
	{
		cout << "抓老鼠" << endl;
	}

};

void playObj(Animal* base)
{
	base->cry(); //有继承  虚函数重写 父类指针 指向子类对象 ==>多态

	// dynamic_cast 运行时类型识别 RIIT

	Dog *pDog = dynamic_cast<Dog*>(base);  //父类对象 ===> 子类对象 向下转型

	if (pDog != NULL)
	{
		pDog->doHome();
	}

	Cat *pCat = dynamic_cast<Cat*>(base);

	if (pCat != NULL)
	{
		pCat->doThing();
	}


}

//const char* p 的const 修饰 让p指向的内存空间 变成只读属性
void printBuf(const char* p)
{
	//p[0] = 'Z';
	char* p1 = NULL;

	//要清楚知道 变量转换之前是什么类型  转换之后是什么类型
	//const char* ===> char*  //把只读属性去掉
	p1 = const_cast<char*>(p);
	p1[0] = 'Z';  //通过p1修改内存空间
	cout << p << endl;
}

int main(int argc, char const *argv[])
{
	char buf[] = "aaaaaaaaaaffffffffffdd";
	const char* buf1 = "sssssssss"; //静态存储区  不能修改
	
	//要确保传入参数所指向的内存空间能修改
	printBuf(buf);
//	printBuf(buf1); //会引起崩溃 不能修改

	system("pause");
	return 0;
}

int main2(int argc, char const *argv[])
{
	Animal a;
	Dog d;
	Cat c;

	Dog* d1 = static_cast<Dog*>(&a);  //可以  有关联的可以转换
	d1->cry();
	d1->doHome();
	d1->printAge();

	playObj(&d);
	playObj(&c);

	Dog* d2 = NULL;
	d2->doHome();
//	d2->printAge(); 不能访问含有成员变量的成员函数  未分配内存

	Animal* pBase = NULL;

	pBase = &d;

	pBase = static_cast<Animal*>(&d);

	//强制类型转换
	pBase = reinterpret_cast<Animal*>(&d);

	{
		Tree t;

		//pBase = static_cast<Animal*>(&t); //c++编译器会做类型检查 无关的不通过
		pBase = reinterpret_cast<Animal*>(&t); //reinterpret_cast 重新编译  强制类型转换
	}

	system("pause");
	return 0;
}

int main1(int argc, char const *argv[])
{
	double dpi = 3.1415926;
	int num1 = (int)dpi;  //C类型转换
	int num2 = static_cast<int>(dpi); //静态类型转换 编译时c++编译器会做类型检查
	int num3 = dpi; //c语言中 隐式类型转换的地方 均可使用 static_cast<>() 进行类型转换

	//char* ===> int*
	char p1[20] = "hello...itcast\0";
	int* p2 = NULL;
	//p2 = static_cast<int*>(p1); //使用static_cast,编译器编译时,会做类型检查 若有错误 提示错误

	p2 = reinterpret_cast<int*>(p1);

	cout << "p1:" << p1 << endl; //%s
	cout << "p2:" << p2 << endl; //%d 输出地址  根据类型输出

	//总结:通过 reinterpret_cast<>() 和 static_cast<>() 把c语言的强制类型转换 都覆盖了

	system("pause");
	return 0;
}

本文截取 c++ primer 第五版 730页

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值