dynamic_cast 与 typeid

 C++中的类型转换分为两种:

  1. 隐式类型转换;
  2. 显式类型转换。

  隐式类型转换一般都是不经意间就发生了,比如int + float 时,int就被隐式的转换为float类型了。

  显示类型转换包括四种方式:dynamic_cast、static_cast、const_cast、reinterpret_cast

 static_cast

  static_cast的转换格式:static_cast <type-id> (expression)

  将expression转换为type-id类型,主要用于非多态类型之间的转换,不提供运行时的检查来确保转换的安全性。主要在以下几种场合中使用:

  1. 用于类层次结构中,基类和子类之间指针和引用的转换;
    当进行上行转换,也就是把子类的指针或引用转换成父类表示,这种转换是安全的;
    当进行下行转换,也就是把父类的指针或引用转换成子类表示,这种转换是不安全的,也需要程序员来保证;
  2. 用于基本数据类型之间的转换,如把int转换成char,把int转换成enum等等,这种转换的安全性需要程序员来保证;
  3. 把void指针转换成目标类型的指针,是及其不安全的;

  注:static_cast不能转换掉expression的const、volatile和__unaligned属性。

 dynamic_cast

    dynamic_cast的转换格式:dynamic_cast <type-id> (expression)

  dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

  在多态类型之间的转换主要使用dynamic_cast,因为类型提供了运行时信息。

 const_cast

  const_cast的转换格式:const_cast <type-id> (expression)

  const_cast用来将类型的const、volatile和__unaligned属性移除。常量指针被转换成非常量指针,并且仍然指向原来的对象;常量引用被转换成非常量引用,并且仍然引用原来的对象。

 reinterpret_cast

  reinterpret_cast的转换格式:reinterpret_cast <type-id> (expression)

  允许将任何指针类型转换为其它的指针类型;它主要用于将一种数据类型从一种类型转换为另一种类型。它可以将一个指针转换成一个整数,也可以将一个整数转换成一个指针,在实际开发中,先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原来的指针值;特别是开辟了系统全局的内存空间,需要在多个应用程序之间使用时,需要彼此共享,传递这个内存空间的指针时,就可以将指针转换成整数值,得到以后,再将整数值转换成指针,进行对应的操作。

#include <iostream>
#include <cstdio>
#include <string>
#include <typeinfo>

using namespace std;

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

class derived: public base{
public:
    virtual void funcB(){
        cout<<"derived"<<endl;
    }
};

void funcC(base *p)
{
    //dynamic_cast会检查p里面是否真存有派生类derived类型的指针,如果存在那么返回该类型的指针,否则返回NULL
    derived* dp = dynamic_cast<derived*>(p);
    if(dp){
        dp -> funcB();
    }else{
        p -> funcA();
    }
}

void funcD(base *p)
{
    derived *dp = NULL;
    if(typeid(*p) == typeid(derived)){
        dp = static_cast<derived*>(p);
        dp -> funcB();
    }else{
        p -> funcA();
    }
}

int main()
{
    base *cp = new derived();
    cout<<typeid(cp).name()<<endl;//base
    cout<<typeid(*cp).name()<<endl;//derived
    funcD(cp);//derived
    funcC(cp);//derived
    base *dp = new base();
    funcC(dp);//base
    funcD(dp);//base
    return 0;
}
时间: 2024-10-24 01:16:43

dynamic_cast 与 typeid的相关文章

typeid详解

在揭开typeid神秘面纱之前,我们先来了解一下RTTI(Run-Time Type Identification,运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许“用指向基类的指针或引用来操作对象”的程序能够获取到“这些指针或引用所指对象”的实际派生类型.在C++中,为了支持RTTI提供了两个操作符:dynamic_cast和 typeid. dynamic_cast允许运行时刻进行类型转换,从而使程序能够在一个类层次结构中安全地转化类型,与之相对应的还有一个

C++中static_cast/const_cast/dynamic_cast/reinterpret_cast的区别和使用

C风格的强制转换较简单,如将float a转换为int b,则可以这样:b = (int)a,或者b=int(a). C++类型转换分为隐式类型转换和显示类型转换. 隐式类型转换又称为标准转换,包括以下几种情况: (1).算术转换:在混合类型的算术表达式中,最宽的数据类型成为目标转换类型: (2).一种类型表达式赋值给另一种类型的对象:目标类型是被赋值对象的类型: (3).将一个表达式作为实参传递给函数调用,此时形参和实参类型不一致:目标转换类型为形参的类型: (4).从一个函数返回一个表达式,

C++中获取数据类型typeid

有时候,为了达到某种目的,我们需要获取数据类型,这个类型无论是内置类型还是自定义类型,包括类类型:  在揭开typeid神秘面纱之前,我们先来了解一下RTTI(Run-Time Type Identification,运行时类型识别),它使程序能够获取由基指针或引用所指向的对象的实际派生类型,即允许"用指向基类的指针或引用来操作对象"的程序能够获取到"这些指针或引用所指对象"的实际派生类型.在C++中,为了支持RTTI提供了两个操作符:dynamic_cast和ty

赋值运算符、拷贝初始化和this指针

一.赋值运算符和拷贝构造函数(重载技术) 赋值运算符和拷贝构造函数有编译器默认提供,但如果想做更复杂的事,需要重载. 1.下面用一个简单的例子先区分一下赋值运算符和拷贝构造函数: #include<iostream> using namespace std; class  alpha { public:     alpha():data(0) {}       //没有参数的构造函数     alpha(int d):data(d) {}  //一个参数的构造函数     void dipla

【C++】深度探索C++对象模型读书笔记--关于对象(Object Lessons)

前言中的内容: 1.什么是C++对象模型? 1.语言中直接支持面向对象程序设计的部分 2. 对于各种支持的底层实现机制 2. C++ class的完整virtual functions在编译时期就固定下来了,程序员没有办法再执行器动态增加或取代其中一个.这使得虚拟调用操作得以快速地派送结果,付出的成本则是执行期的弹性. 3. 全局对象在main()函数之前便完成初始化. 第一章 关于对象 1. 在C++中,有两种class data members:static 和 nonstatic,以及三种

c++ 杂

1.强制类型转换: 一般使用的是c风格的类型转换,进行简单数据类型间的转换,而对于类之间的转换,使用4个转换符. reinterpret_cast <new_type> (expression): 只用于指针和引用, 将一个指针类型强制转换为另一个指针类型,不做任何操作,仅返回转换类型后的指针,与c的强制类型转换效果相同.用于底层的强制类型转换,可将指针转换为整形.只是对底层的二进制数据换一种读法. static_cast : 可以进行 类型定义的显示转换,和指针类型的转换.对与指针的转换,允

GCC 编译选项

http://www.cnblogs.com/xmphoenix/archive/2011/03/21/1989944.html GCC 编译选项(转) gcc提供了大量的警告选项,对代码中可能存在的问题提出警 告,通常可以使用-Wall来开启以下警告:            -Waddress -Warray-bounds (only with -O2) -Wc++0x-compat            -Wchar-subscripts -Wimplicit-int -Wimplicit-

【转】static_cast和reinterpret_cast

1 static_cast和reinterpret_cast揭秘 收藏 2 本文讨论static_cast<> 和 reinterpret_cast<>. 3 4 reinterpret_cast可以转换任意一个32bit整数,包括所有的指针和整数.可以把任何整数转成指针,也可以把任何指针转成整数,以及把指针转化为任意类型的指针,威力最为强大!但不能将非32bit的实例转成指针.总之,只要是32bit的东东,怎么转都行! 5 static_cast和dynamic_cast可以执行

【C++对象模型】第一章 关于对象

1.C/C++区别 C++较之C的最大区别,无疑在于面向对象,C程序中程序性地使用全局数据.而C++采用ADT(abstract data tpye)或class hierarchy的数据封装.类相较于C的struct不仅只包含了数据,同时还包括了对于数据的操作.在语言层面上C++带来了很多面向对象的新特性,类.继承.多态等等.新特性使得C++更加强大,但同时却伴随着空间布局和存取时间的额外成本.这些额外成本主要由 virtual引起,包括: virtual function 机制,用来支持"执