static_cast&dynamic_cast

stactic_cast用来执行任意明确定义的类型转换,以及反变换。但其只是暴力转换,并不负责保证转换的安全性。

1、基本数据类型之间的转换,int->char,int->enum,char->int,int->float,float->int,但精度的丢失不在static_cast的考虑范围,需要开发者自己考虑。

2、将任何非常量对象的地址存入void* & 找回存在于void*指针中的值。

char *c = new char[100];

c = "12222";

cout<<c<<endl;

这里c本身是一个指向字符数组的指针,但cout语句中,对于const char*或者 char*类型的指针,只会输出他们指向的值,而不会输出其本身存储的地址。如果想输出地址,只能显示转换一下,void* ptr = static_cast<void*>(c),此时即可输出c保存的地址;

同理也可以用static_cast进行上述过程的逆过程,如果有一个指针因为要获取地址的原因被显示转换成了void*,此时想将其转换回来,则可以这样使用:char *ptr2 = static_cast<char*>(ptr);此时cout<<ptr2;即可输出值而非地址。

	char* c = new char[100];
	c = "12222";
	cout << "c: " << c << " ";
	void* ptr1 = static_cast<void*>(c);
	cout << "ptr1: " << ptr1<<" ";
	char* ptr2 = static_cast<char*>(ptr1);
	cout << "ptr3: " << ptr2;
	cout << endl;

输出结果:

3、类层次结构中父类与子类之间指针或者引用的转换。&dynamic_cast

类中父类子类之间的指针、引用转换有两类情况,一类是从父类转换为子类,另一类是从子类转换为父类。前者叫下行转换,后者叫上行转换。上行转换较为安全,但下行转换并不安全。

	A *ptr = new A;
	C *cptr = static_cast<C*>(ptr);
	C *dptr = dynamic_cast<C*>(ptr);//必须有多态产生,才可用dynamic_cast
	cout << "cptr:" << cptr << " dptr: " << dptr;

其中类定义如下:

class A{ 
public:
	 A() = default;
	 virtual void func(){}
	int m; };
class B{ int m; };
class D{
	virtual void func(){};
};
class C :public A, B{
public:
	int temp;
};

由于类的继承关系,指向父类指针既可以指向子类对象,也可以指向子类对象。但子类指针不可指向父类对象,这就是问题所在。

上述情况即一个指向父类对象的父类指针,被强制转换为一个指向父类对象的子类指针,因为子类中可能有父类中没有的属性与函数,如果用转换过后的指针去访问子类专属的成员,那就会造成访问越界,内存崩溃。如果使用static_cast强行转换,程序不会报错,也不会做运行时类型检查,这就是一个巨大的隐患。

dynamic_cast所做的就是在运行时进行类型检查,此时,检测到这样的转换不合适,就会将转换后的指针置NULL,保证程序不会崩溃。

因为引用没有NULL引用,所以dynamic_cast引用遇到此类情况,就会抛出std::bad_cast异常。

tip:static_cast & dynamic_cast可以做从非const类型到const类型,但反之不行。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章