C++类型转换

C++有可以使用static_cast、dynamic_cast、const_cast、reinterpret_cast来进行类型的转换。现在将每一个的使用方法进行一下总结。

1.static_cast

这个运算符的功能是把一个表达式转换为某种类型,但是没有运行时类型检查来保证转换的安全性。可以用来转换的类型主要如下:

  • 类中基类和派生类之间的指针或者引用的转换:向上转换是安全的(派生类的指针转换为基类),但是向下转换的时候由于没有类型检查,所有是不安全的。
  • 基本数据类型之间的转换。
  • 空指针转换为目标类型的空指针。
  • 任何类型的表达式转换为void类型。

static_cast不能把原来表达式中的const、volatile、_unaligned属性转换成没有。请看下面例子

1    char firstChar = 'A';
2    int firstInt = static_cast<int>(firstChar);
3    const char* constStr = "this is a test string";
4    char* str = static_cast<char*>(constStr);

上面的第4行代码是不能编译通过的。

2.dynamic_cast

dynamic_cast的转换需要目标类型和源对象有一定的关系:继承关系。换句话说就是dynamic_cast就是用来检查两者是否有继承关系,所有dynamic_cast只能接受类对象的指针或者是引用的类转换。用法表达式如下:

dynamic_cast<type_id>(expession)。type_id只能是类的指针、引用或者是void*。如果type_id是一个指针或者引用,那么expression也必须是指针或者引用,type_id和expression必须对应起来。

dynamic_cast在执行的时候决定真正的类型,如果转换是安全的,dynamic_cast就会传回适当的转换过的指针,如果转换是不安全的,就会返回空指针。

在类层次向上转换的时候,dynamic_cast和static_cast的效果是一样的。

在类层次向下转换的时候,由于dynamic_cast会做类型检查,所有比static_cast更加的安全。如下的例子:

class person
{
public:
   int n_num;
   virtual void doSomething()
   {
      cout << "i am a person" << endl;
   }
};
class colorPerson :public person
{
public:
   char* mName;
};
void change(person *person)
{
   colorPerson * cp1 = static_cast<colorPerson*>(person);
   cout << "start to call cp1" << endl;
   if (cp1 != NULL)
   {
      cp1->doSomething();
   }
   else 
   {
      cout << "cp1 is null" << endl;
   }
   colorPerson *cp2 = dynamic_cast<colorPerson*>(person);
   cout << "start to call cp2" << endl;
   if (cp2!= NULL)
   {
      cp2->doSomething();
   }
   else
   {
      cout << "cp2 is null" << endl;
   }
}
int main()
{
   person *p1=new person();
   change(p1);
   colorPerson *cp1 = new colorPerson();
   change(cp1);

    return 0;
}
View Code

输出结果是这样的:

 在定义person类的时候,我们是定义了一个virtual的dosomething(),这个virtual对应dynamic_cat是必须的,如果没有virtual,就会报编译错误。因为dynamic_cast转换是在运行时进行转换,运行时转换就需要知道类对象的信息(继承关系等)。如何在运行时获取到这个信息——虚函数表。

原文地址:https://www.cnblogs.com/VARForrest/p/15671484.html