一点一滴成长

导航

类型转换

  dynamic_cast<>

  C++运行时类型识别RTTI的功能由两个运算符实现:dynamic_cast和typeid,dynamic_cast用于将基类指针或引用转换为派生类指针或引用,一般在以下的情况我们会使用它:想使用基类指针或引用执行派生类的某个操作,但该操作不是虚函数,因为如果该操作是虚函数的话会自动选择执行派生类的虚函数。但我们应该尽量使用虚函数,当无法使用虚函数的时候再使用dynamic_cast。

  当使用dynamic_cast将基类指针或引用转换为派生类指针或引用时,基类必须是多态类型(即包含一个虚函数),且如果要转换的两个对象不是父子关系,dynamic_cast返回NULL,eg:

class CParent
{
public:
    virtual void test() {}
 };

class CChild : public CParent
{    
};

CParent* p = new CChild;
CChild* pt = dynamic_cast<CChild*>(p);
if (pt != nullptr)
{
    //do something
}
else
{
    //error
}

 如果一个类从两个类派生,那么这两个父类指针也不能通过dynamic_cast<>来互相转换,如下:

class A
{
    virtual void func(){}
};

class B
{
    virtual void func() {}
};

class C : public A, public B
{

};

A* p1 = new C;
B* p2 = dynamic_cast<B*>(p1); // 错误
B* p3 = dynamic_cast<C*>(p1); // 正确,先通过dynamic_cast将A类指针转换为C类指针,再将C*类型(子类指针)强制转换为B*类型(父类指针)

 

  static_cast<>

  dynamic_cast将基类指针或引用转换为派生类指针或引用的使用条件是基类必须是多态类型,static_cast就没有这个限制,由于没有动态类型检查,所以它是不安全的,如下代码所示,所以如果使用static_cast进行转换的话必须由开发人员保证转换的安全性:

class CParent
{
public:
    virtual void test() {}
 };

class CChild : public CParent
{    
};

CParent* p = new CParent;
CChild* pt = static_cast<CChild*>(p);
if (pt != nullptr)
{
    pt->test(); //error
}

  static_cast还可以用来将enum class转换为指定类型:

 

enum class EType{ eType1, eType2};

int iType1 = EType::eType1; // 错误 !
int iType2 = static_cast<int>(EType::eType1); // 正确

 

  将派生类指针转换为基类指针可以直接进行转换,即可以将派生类指针直接赋给一个基类指针来使用。

  const_cast<>

  const_cast主要针对const和volatile的转换,它可以使一个本来不是const类型的数据转换成const类型或者将const属性去掉,eg:

    string str("test"); 
    char *inbuf = const_cast<char*>(str.c_str());

  reinterpret_cast<>

  reinterpret_cast可以用于进行没有任何关联之间的转换,通过它任何指针都可以转换成其它类型的指针,一般其与强制类型转换功能相同,没有安全检查:

    char* p = new char[4];
    int *pt = reinterpret_cast<int*>(p); //等同于 int *pt = (int*)p;

 

posted on 2018-04-12 14:44  整鬼专家  阅读(181)  评论(0编辑  收藏  举报