Regular cast vs. static_cast vs.dymamic_cast in C++

介绍C++类型转换的用法。

1.static_cast

static_cast用与强制隐式类型转换,即隐式类型转换的反方向。static_cast,限制条件少,不进行运行时检验。

必须用于当你知道对象的具体类型时,这样检验是不必要的,否则,不安全。

example:

void func(void *data) {
  // Conversion from MyClass* -> void* is implicit
  MyClass *c = static_cast<MyClass*>(data);
  ...
}

int main() {
  MyClass c;
  start_thread(&func, &c)  // func(&c) will be called
      .join();
}

在这个例子中,你已经知道传入的是一个MyClass 对象,没有必要进行运行时检验。

如果将一个非MyClass 对象传入func中,会如何呢,看下面code,

#include<iostream>
using namespace std;
class A{
	public:
		A()
		{
			i=0;
			j=12;
		}
		int i;
		int j;
};

void cast_f(void *ptr)
{
	A * p=static_cast<A *>(ptr);
	cout<<p->i<<endl;
	cout<<p->j<<endl;
} 
int main()
{
	int a=11;
	int * p=&a;
	cast_f(p);
	cin.get();
	return 0;
}
输出11和一个未知数。而不是0和12。 这就要我们确保已知传入的对象类型。否则,不安全。

2.dynamic_cast

dynamic_cast用在当你不知道对象的动态类型是什么的时候,而你想在一个你认定为继承类对象身上执行继承类的操作函数,但你的手上却只有一个指向基类对象的指针或者引用。若为downcast并且类型参数不为多态时,不能使用dynamic_cast,编译器报错。

dynamic_cast 返回一个null指针,如果对象的类型不是以将要转换为的类型为基类的话。即,非派生类对象转为基类对象,或者基类对象转为派生类对象,均返回null指针。

#include<iostream>
using namespace std;
class A{
	public:
		virtual void f(){
			cout<<"A"<<endl;
		}
};
class B:public A{
	public:
	void dynamic_f()
	{
		cout<<"called dynamic_f()"<<endl;
	} 
};
int main()
{
	A a;
	B *b=dynamic_cast<B *>(&a);//when downcast, if a is not object of class B,return null pointer.
	if(!b)
	{
		cout<<"null"<<endl;
	}
	else
	{
		cout<<"not null"<<endl;
	}
	A *aa=0;//基类指针 
	B bb;
	aa=&bb;//指向派生类
	//aa如何调用dynamic_f()呢? aa.dynamic_f()当然不行了,编译不通过
	B *ba=dynamic_cast<B*>(aa);
	ba->dynamic_f();
	cin.get();
	return 0;
}


这个例子中,将基类对象转换为派生类对象,返回一个null指针。

up-cast(向上转换)是隐式转换,对static_cast,dynamic_cast,without any cast均有效。

3.Regular cast

Regular cast 又称为C风格类型转换。C-style cast,结合const_cast,static_cast,reinterpret_cast,但是它是不安全的,因为不支持dynamic_cast。

通常在数字转换时用C-style cast,其他用c++风格的cast。另外,c++风格的更易读。


你可能感兴趣的:(C++,类型转换,cast)