C++学习笔记(四)--类型转化 static_cast const_cast reinterpret_cast dynamic_cast


类型转换--c++希望能设置正确的类型,就不用转换了。
static_cast 合理的转换: 数值类型之间,有一方是void*指针类型之间到转换。  可以是类型 也可以是一方为void *的指针

const_cast 常量转变量,用于临时去掉const限制。  const_cast对象的类型必须为指针 引用 或指向对象成员的指针. 

reinterpret_cast  任意两种指针类型之间,指针与数值之间  

dynamic_cast (重点)

 作用:将一个基类对象指针(或引用)cast到继承类指针,dynamic_cast会根据基类指针是否真正指向继承类指针来做相应处理, 

       即会作一定的判断。 
       对指针进行dynamic_cast,失败返回null,成功返回正常cast后的对象指针; 
       对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用。 
   注意:dynamic_cast在将父类cast到子类时,父类必须要有虚函数。例如在下面的代码中将CBasic类中的test函数不定义成 virtual时,编译器会报错:error C2683: dynamic_cast : “CBasic”不是多态类型 






#include <iostream>
#include <cstdlib> //c语言头文件在c++中有对应的  前面加c 后面去掉.h

using namespace std;

class Base
{
	public: 
	virtual	 void Say() {cout << "hello base" << endl;}		
};
	
class Derive:public Base
{
	public:
	 void Say() {cout << "hello derive" << endl;}
};

int main()
{
	/*数值类型转换,void*到转换 */
	int i = static_cast<int>(1.213);
	cout << i << endl;
	//zhuanhuan.cpp:24: error: invalid conversion from ‘void*’ to ‘int*’
	int *p = static_cast<int *>(calloc(sizeof(int),10));	
	free(p);


	//如何改变常量的值?
	const int k = i; //这里和c++优化的关系,用变量初始化无法优化。
//	const_cast<int>(k) = 123; 
//	 error: invalid use of const_cast with type ‘int’, which is not a pointer, reference, nor a pointer-to-data-member type

  	//所以要改变k 应该这么做 转换为引用类型
	const_cast<int &>(k) = 456;
	cout << k << endl; //456


	//1 指针类型之间转化
	float f = 123.45;
	p = reinterpret_cast<int *>(&f);
	cout << *p << endl; //1123477094 其实这样转没什么意义
	//2 指针转化为整数
	unsigned int num = reinterpret_cast<int>(p);
	cout << "num = " << num <<endl; //3219756016 其实是指p 所指向的地址
	//3 整数转化为指针
	int *p2 = reinterpret_cast<int *>(num);
	cout << "*p2= " << *p2	 <<endl; //*p2=1123477094 p2中存放的地址值是num
	即使类型转换,值是不会变的
	//强制类型转换
	int n = (int)12.34;
	cout << n << endl;//12
	n = int(23.45);
	cout << n << endl;//23
	n = int();
	cout << n << endl; //0

	int m(100);	//初始化
	cout << m << endl;

	int x(); //这是一个函数声明
	
	Base *b = new Base();
	Derive *d = new Derive();
	b->Say();
	d->Say();
	
	//这个转换是正确的 基类向父类
	//b = dynamic_cast<Base *>(d);
	//b->Say();

	d = dynamic_cast<Derive *>(b);
	//如果不把基类到Sayhello 设置为虚函数 这个转换就会出现不是多态的错误
	//zhuanhuan.cpp:95: error: cannot dynamic_cast ‘b’ (of type ‘class Base*’) to type ‘class Derive*’ (source type is not polymorphic)
	
}

对于const数据我们更要这样保证:绝对不对const数据进行重新赋值。

如果我们不想修改const变量的值,那我们又为什么要去const呢?

两种情况:

1 我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数确实const的,但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。

void print(char *str)
{
	cout << str << endl;
}

	const char* p3 = "hello world";
	// 不能从const char * 转变为 char*
	//print(p3);
	print(const_cast<char *>("hello world"));

2 const对象调用自己的非const方法时

class A
{
	public:
		void print() {cout << "a" << endl;}
		void print()const {cout << "const a" << endl;}
};

	const A b;
	b.print();//const a const方法
	const_cast<A&>(b).print(); //a 非const方法 


3 const指针指向一个非const对象,但现在想修改对象,但手头上只有const指针时

	int a = 100;
	const int *p2 = &a;
	*const_cast<int *>(p2) = 200;
	cout << a << endl;



什么时候需要dynamic_cast

class Base
{
public:
	virtual  void print() {cout << "base" << endl;}
};

class Child : public Base
{
public:
	void print() { cout << "Child" << endl;}
	void print2() {cout << "print2 child " << endl;}
};

	Base *pb = new Child;
	pb->print(); //这个是虚函数 可以通过父指针访问 //虚函数放在虚表中 通过虚函数指针访问
	// pb->print2(); 
	dynamic_cast<Child *>(pb)->print2(); //这个不是虚函数  放在代码区 需要转变类型访问




ps:
gcc 如何编译 ccp?
gcc zhuanhuan.cpp -lstdc++

你可能感兴趣的:(C++学习笔记(四)--类型转化 static_cast const_cast reinterpret_cast dynamic_cast)