深入理解 CPP 之 type conversion

backround

基类对象转换为派生类对象,是不安全的

  • 派生类是包含于基类的,即基类的“体积”是小于派生类的

  • 如果一个指向基类的指针强转为指向派生类的指针(该指针始终指向基类,只是指针类型变了),再通过该指针调用派生类的特有方法或者数据

  • 就会访问到未知的数据,从而导致崩溃

  • 所以这种转换在dynamic_cast中就会报错


派生类对象转换为基类对象,是安全的

  • 理由同上,派生类是包含于基类的,因此对方法或数据的使用,不会造成越界

派生类指针只能指向派生类,基类指针可以指向基类或派生类


type conversion针对的是指针和引用

  • 引用可以理解为指针的语法糖



static_cast

用途

  • 等价于C里面的强制转换,可以将non-const对象转为const对象
  • 用于基本数据类型之间的转换(例如int转换为char
  • 把空指针转换为目标类型的空指针
  • 把任何类型的表达式转换成void类型
  • 也可以用于类对象之间的转换(但没有动态类型检查,所以不安全)

格式:static_cast<type-id>(expression);


优点

更加明显,能够一眼看出转换为什么类型

更加安全


缺点

没有运行时类型检查来保证转换的安全性(dynamic_cast

不能用于在不同类型指针之间的转换

不能用于整型和指针之间的的转换

不能用于不同类型的引用之间的转化

不能去除掉已有对象的const或volatile,或者__unaligned属性


总结

可以理解为C里面强制转换的平替,但又有一些局限性




dynamic_cast

用途

  • 将基类的指针或引用安全地转换为派生类的指针或引用(前提:该基类指针指向的是派生类,同时基类必须有虚函数
  • 或是将派生类的指针或引用安全地转换为基类的指针或引用(基类不需要有虚函数)

格式:dynamic_cast <type-id>(expression),其中type-id可以是类指针,类引用或void*expression也要是对应的类型


若对指针进行dynamic_cast,失败返回nullptr,成功返回正常cast后的对象指针

若对引用进行dynamic_cast,失败抛出一个异常,成功返回正常cast后的对象引用


代码

#include <iostream>
#include <assert.h>

using namespace std;

// 父类
struct Tfather {
    virtual void f() { cout << "father's f()" << endl; }
};

// 子类
struct Tson : public Tfather {
    void f() { cout << "son's f()" << endl; }
    int data; // 子类独有的成员
};

int main() {
    Tfather father;
    Tson son;
    son.data = 123;

    Tfather *pf;
    Tson *ps;

    //    上行转换:没有问题
    ps = &son;
    pf = dynamic_cast<Tfather *>(ps);
    pf->f();

    //    下行转换(pf实际指向子类对象):没有问题
    pf = &son;
    ps = dynamic_cast<Tson *>(pf);
    ps->f();
    cout << ps->data << endl; // 访问子类独有成员有效

    //    下行转换(pf实际指向父类对象):含有不安全操作,dynamic_cast则返回nullptr(而static_cast则会无视)
    pf = &father;
    ps = dynamic_cast<Tson *>(pf);
    assert(ps != nullptr); // 违背断言,阻止以下不安全操作
    ps->f();
    cout << ps->data << endl; // 不安全操作,对象实例根本没有data成员
}
Cpp

总结

主要用于类之间的转换

上行转换(派生类转换为基类),和static_cast等效

下行转换(基类转换为派生类),dynamic_cast具有类型检查功能,更加安全

相比static_cast会更加耗时,因为dynamic_cast会在运行时进行类型检查来保证转换的安全性




reinterpret_cast

用途

  • 可以将整型转换为指针,也可以把指针转换为数组,或是将指针和引⽤之间进⾏转换

  • 从底层对数据进⾏重新解释;依赖具体的平台,可移植性差

  • 等价于C里面的强制转换

格式:reinterpret_cast<type-id>(expression);type-id必须是一个指针、引用、算术类型、函数指针或者成员指针,用于类型之间进行强制转换




const_cast

用途

  • 给已有对象添加const或删除const,或是volstile
  • 是唯一一个可以操作常量的转换符
  • 常量指针(或引用)被转化为非常量指针(或引用),并且仍然指向原来的对象
  • 一般用于修改底层指针,如const char *p形式

格式:const_cast <type-id> (expression);


 上一篇
The Google File System The Google File System
gfs为google内部的文件系统,其开源实现为hdfs,大数据领域标准的开源实现 GFS是一个存储非结构化数据的存储系统,和bigtable(列存储,存储结构化数据,关系模型,表结构)是相对应的 GFS只存储数据,不关心数据的结构和内容是
2022-10-24
下一篇 
MapReduce: Simplified Data Processing on Large Clusters MapReduce: Simplified Data Processing on Large Clusters
mapreduce的背景随着业务的增长,待处理的数据集越来越多,单机无法在规定时间内对海量数据进行处理 因此需要同时使用多台机器对数据进行处理 而大规模的数据处理,需要同时应对多机并行协同,网络通信,处理错误,提高执行效率等问题 但这些问题
2022-10-23