C++类型转换dynamic_cast解析

C++的类型转换有四种 const_cast, reinterpret_cast, static_cast, dynamic cast

这边举一个dynamic cast的小例子

#include <iostream>

using namespace std;

class BaseClass{
    public :
    int m_iNum;

    virtual void foo() {}; //基类必须有虚函数。保持多态特性才能使用dynamic_cast
};

class DerivedClass : public BaseClass{
    public :
    char* m_szName;

    DerivedClass(char* str) {
        m_szName = new char[strlen(str) + 1];
        strcpy(m_szName, str);
    }

    ~DerivedClass(){
        if(m_szName != NULL){
            delete []m_szName;
            m_szName = NULL;

        }
    }
    void bar() {};
};

int main() {
    //64位系统, int:4, vtable_prt:8 输出为16
    cout << "sizeof(BaseClass) = " << sizeof (BaseClass) << endl;
    //64位系统, 4 + 8 + 8 = 24
    cout << "sizeof(DerivedClass) = " << sizeof (DerivedClass) << endl;

    char *p = "abc";
    BaseClass *pb = new DerivedClass(p);
    cout << "sizeof(*pb): " << sizeof (*pb) << endl; // 16

    DerivedClass *pd1 = static_cast<DerivedClass *>(pb); //子类->父类,静态类型转换,正确但不推荐
    DerivedClass *pd2 = dynamic_cast<DerivedClass *>(pb); //子类->父类,动态类型转换,正确

    cout << pd1->m_szName << endl; //abc
    cout << pd2->m_szName << endl; //abc

    cout << "sizeof(*pd1): " << sizeof (*pb) << endl; //16
    cout << "sizeof(*pd2): " << sizeof (*pb) << endl; //16

    BaseClass* pb2 = new BaseClass();
    DerivedClass *pd21 = static_cast<DerivedClass *>(pb2); //父类->子类,静态类型转换,危险!访问子类m_szName成员越界
    DerivedClass *pd22 = dynamic_cast<DerivedClass *>(pb2); //父类->子类,动态类型转换,安全的。结果是NULL

    cout << "sizeof(*pd21): " << sizeof (*pb) << endl; //16
    cout << "sizeof(*pd22): " << sizeof (*pb) << endl; //16

    cout << pd21 <<endl; //0x7f9a7b403a60
    //如果访问 pd21 -> m_szName则segmentation fault
    cout<< pd22 <<endl; //0 这里是NULL
    return 0;
}

输出结果为:

sizeof(BaseClass) = 16
sizeof(DerivedClass) = 24
sizeof(*pb): 16
abc
abc
sizeof(*pd1): 16
sizeof(*pd2): 16
0x7f9a7b403a60
0
sizeof(*pd21): 16
sizeof(*pd22): 16
时间: 2024-09-30 10:28:46

C++类型转换dynamic_cast解析的相关文章

强制类型转换细节解析

基础类型范围: byte b = 44; //byte占1个字节,取值范围为-128~127(-2的7次方~2的7次方-1) char c = 'b'; //当转换为数字时,对应为字符的ASCII码表的十进制数 short s = 1024; //short占2个字节,-2的15次方~2的15次方-1(-32768~32767) int i = 40000; //int占4个字节,-2的31次方~2的31次方-1(-2147483648~2147483647) long l = 12463l;

C++杂记:运行时类型识别(RTTI)与动态类型转换原理

运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. 静态类型的情形 C++中支持使用typeid关键字获取对象类型信息,它的返回值类型是const std::type_info&,例: #include <typeinfo> #include <cassert> struct B {} b, c; struct D : B {

【转载】C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理

原文:C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理 运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. 静态类型的情形 C++中支持使用typeid关键字获取对象类型信息,它的返回值类型是const std::type_info&,例: #include <typeinfo> #include <cassert>

C/C++杂记:运行时类型识别(RTTI)与动态类型转换原理

运行时类型识别(RTTI)的引入有三个作用: 配合typeid操作符的实现: 实现异常处理中catch的匹配过程: 实现动态类型转换dynamic_cast. 1. typeid操作符的实现 1.1. 静态类型的情形 C++中支持使用typeid关键字获取对象类型信息,它的返回值类型是const std::type_info&,例: #include <typeinfo> #include <cassert> struct B {} b, c; struct D : B {

static_cast 、const_cast、dynamic_cast、reinterpret_cast 关键字简单解释

static_cast .const_cast.dynamic_cast.reinterpret_cast 关键字简单解释: Static_cast 静态类型转换 ①用于类层次结构中基类(父类)和派生类(子类)之间指针或引用的转换. 进行上行转换(把派生类的指针或引用转换成基类表示)是安全的: 进行下行转换(把基类指针或引用转换成派生类表示)时,由于没有动态类型检查,所以是不安全的. ②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum.这种转换的安全性也要开发人员来保

c++中四种类型转换

reinterpret_cast<目标类型>(原类型变量)//重解释类型转换 dynamic_cast<new_type>(expression)//动态类型转换 static_cast<new_type>(expression)//静态类型转换 const_cast<new_type>(expression)//返回一个指向非常量的指针 1.const_cast:常量指针被转化成非常量的指针,并且仍然指向原来的对象:常量引用被转换成非常量的引用,并且仍然指

关于c++中的类型转换符

const_cast(链接) 用来去掉const或volatile属性 volatile: 用于并行设备的硬件寄存器(状态寄存器), 中断服务子程序中会访问到的非自动变量, 多线程中被几个任务共享的变量 一般用来将常量指针变为非常亮指针, 常量引用变为非常量引用, 常量对象变为非常量对象 static_cast(链接) 强制类型转换:(不含类型转换的安全检查) 子类指针转换为父类指针,父类指针可以转换为子类指针(但是不安全) 用于: 类中基类和派生类指针和引用的转换 基本类型转换(相当于c语言中

More Effective C++

条款一:指针与引用的区别 指针与引用看上去完全不同(指针用操作符'*'和'->',引用使用操作符'.'),但是它们似乎有相同的功能.指针与引用都是让你间接引用其他对象.你如何决定在什么时候使用指针,在什么时候使用引用呢? 首先,要认识到在任何情况下都不能用指向空值的引用.一个引用必须总是指向某些对象.因此如果你使用一个变量并让它指向一个对象,但是该变量在某些时候也可能不指向任何对象,这时你应该把变量声明为指针,因为这样你可以赋空值给该变量.相反,如果变量肯定指向一个对象,例如你的设计不允许变量为

C++primer第五章 表达式

表达式由一个或多个操作数通过操作符组合而成.最简单的表达式仅包含一个字面值常量或变量.较复杂的表达式则由操作符以及一个或多个操作数构成. 每个表达式都会产生一个结果. 5.1. 算术操作符 表 5.1 按优先级来对操作符进行分组——一元操作符优先级最高,其次是乘.除操作,接着是二元的加.减法操作. 算术操作符 +.-.* 和 / 具有直观的含义:加法.减法.乘法和除法.对两个整数做除法,结果仍为整数,如果它的商包含小数部分,则小数部分会被截除: int ival1 = 21/6; // inte