第十课C++类型转换

在C语言中,类型的转换是统一的也就是 TYPE b=(TYPE)a,例如:int b=(int)a;在C++中就不一样了,C++提供了四种类型转换操作。
C++风格的类型转换提供了4种类型转换操作符来应对不同场合的应用。
static_cast 静态类型转换。如int转换成char
reinterpreter_cast 重新解释类型
dynamic_cast 命名上理解是动态类型转换。如子类和父类之间的多态类型转换。
const_cast, 字面上理解就是去const属性。
4种类型转换的格式都是一样的,以static_cast来进行说明为:
TYPE B = static_cast (a)

在C++中,dynamic_cast和static_cast都是用来转型的操作符,两者不合理的运用可能会导致在编译期合法的类型转换操作却在运行期也会引发错误,当转型操作涉及到对象指针或引用时,更易发生错误。 这两者又有什么区别呢?
  1、dynamic_cast操作符会在运行期对可疑的转型操作进行安全检查,而static_cast操作符不会进行安全检查;
  2、dynamic_cast仅对多态有效(转型的源类型必须是多态,但与转型的目标类型是否多态无关),而static_cast可施加与任何类型;
  3、从派生类到基类的 dynamic_cast 可以进行,这称为向上转型;
  4、从基类到派生类的 dynamic_cast 不能进行,称为向下转型;
  5、有继承关系,派生类可通过dynamic_cast向基类转换;
  6、没有继承关系,不能通过dynamic_cast互换;


关于基本类型的用法
#include <cstdlib>
#include <iostream>
using namespace std;

//static_cast 和 reinterpret_cast 的用法
int main()
{
	double dPi=6.6666;
	int num1 = static_cast<int> (dPi); //c++的新式的类型转换运算符  
	int num2 = (int)dPi;				//c语言的 旧式类型转换 
	int num3 = dPi;						//隐士类型转换
	cout << "num1:" << num1 << " num2:" << num2 << " num3:" << num3 << endl;

	char *p1 = "A" ;
	int *p2 = NULL;
	//2 基本类型能转换 但是不能转换指针类型(注:仅仅是基本类型不能转换)
	//p2 = static_cast<int *> (p1); //"static_cast": 无法从"char *"转换为"int *"
	//3 可以使用  reinterpret_cast 进行重新解释 
	p2 = reinterpret_cast<int *> (p1);
	cout << "p1 " << p1 << endl;
	cout << "p2 " << p2 << endl;         //打印出p2指向的地址
	cout << "p2 " << *p2 <<endl;         //打印出p2指向的地址里面的值,也就是A的acsii码,65
	cout << "p2 " << (char *)p2 <<endl;  //打印出A
	return 0;
}

在这里插入图片描述

关于类的基本用法
#include <cstdlib>
#include <iostream>
using namespace std;

// dynamic_cast用法和reinterpret_cast用法
class Animal 
{
public:
	virtual void  cry() {
			cout << "I am Animal" << endl;;
	}
};

class Dog : public Animal 
{
public:
	virtual void  cry(){
		cout << "wangwang " << endl;
	}
	void doSwim(){ 
		cout << "我要学习" << endl; 
	}
};

class Cat : public Animal
{
public:
	virtual void  cry(){
		cout << "miaomiao " << endl;
	}
	void doTree() { 
		cout << "我要向上" << endl; 
	}

};



class Book
{
public:
	Book(void){
		cout << "Book构造函数" << endl;
	}
	void printP()
	{
		cout << price << endl;
	}

public:
	int price;

};

//典型用法 把形参的只读属性去掉
void Opbuf(const char *p)
{
	cout << p << endl;
	char *p2 = const_cast<char*>(p);
	p2[0] = 'b';
	cout << p << endl;
}

int main()
{
		
	const char p1[12] = "11111111111";
	Animal *base = new (Animal);
	base->cry();
	//1 可以把子类指针赋给 父类指针 但是反过来是不可以的 需要 如下转换
	//pdog = base;  
	Dog *pDog = static_cast<Dog *> (base);  //--可以有基类转换成派生类,或者子类转换成基类
	pDog->cry();//由于K的类型是Animal,执行的是Animal里面的cry函数

	//2 把base转换成其他不相关的就是产生错误
	//Book *book= static_cast<Book *> (base);

	//3dynamic_cast的用法 -- 只能子类转换成基类
	Dog *pgone =new(Dog);
	Animal *base2 = dynamic_cast <Animal *>(pgone);

	base2->cry();
	//4  reinterpret_cast //可以强制类型转换
	//为指针book2申请一个内存空间,但是不进入Book的构造函数
	Book *book2= reinterpret_cast<Book *> (base);
	book2->price=666;
	book2->printP();

	//5 const_cast用法
	Opbuf(p1);
	return 0;
}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值