跳至主要內容

类型强制转换

Entity大约 2 分钟

类型强制转换

提示

类型转换有四种方式,分别是:static_cast , const_cast,dynamic_cast和reinterpret

static_cast

基本类型的转换,但不能用于基本类型指针之间的转换(void指针和基本类型指针之间可以)

// 
double d = 0;
int i = static_cast<

用于有继承关系的子类与父类之间的指针或引用的转换

空类型指针转换为任意类型的指针

int a = 0;;
int *b = &a;
// 这种转换极容易出错,需保证转换后的类型就是指针原先的类型
int *c = static_cast<int *>(b);

const_cast

const_cast转换符用来移除变量的const或volatile限定符。

const int constant = 21;
const int * constantPtr = &constant;
int * constantCast = const_cast<int *>(constantPtr);

传统方式实现const_cast运算符

const int constant = 21;
int * modifier = (int*)(&constant);

如果我们不想修改const变量的值,那我们又为什么要去const呢?

原因是,我们可能调用了一个参数不是const的函数,而我们要传进去的实际参数确实const的,但是我们知道这个函数是不会对参数做修改的。于是我们就需要使用const_cast去除const限定,以便函数能够接受这个实际参数。

void pointer(int *val){
    cout << val << endl;
}

int main(void){
    const int constant = 21;
    pointer(constant); // error

    pointer(const_cast<int *>(constant)); // ok
}

dynamic_cast

dynamic_cast是四个强制类型转换操作符中最特殊的一个,它支持运行时识别指针或引用

父转子难,子转父易

// 类似于C# 里面的协变跟逆变
class Base {
public:
    Base() {};
    virtual void show()
    {
        cout << "this is base class" << endl;
    }
};

class derived : public Base {
public:
    derived() {};
    void show() {
        cout << "this is derived class" << endl;
    }
};

int main(){
    // 子类转换为父类
    Base* base = new derived;
    if (derived* d = dynamic_cast<derived*>(base)) {
        cout << "derived-》base." << endl;
        d->show();
    }
    // 父类转换为子类,使用指针转换会失败
    Base* base2 = new Base;
    if (derived* d = dynamic_cast<derived *>(base2)) {
        cout << "base -》 derived." << endl;
        base2->show();
    }
    else {
        cout << "base -》 derived转换失败" << endl;
    }
    // 可以改为引用
    Base base3;
    Base& base4 = base3;
    try
    {
        derived& d = dynamic_cast<derived&>(base4);
        d.show();
        cout << "Base -> derived" << endl;
    }
    catch (const std::exception& e)
    {
        cout << e.what() << endl;
        cout << "将父类转换为子类失败" << endl;
    }

    derived de;
    Base& Base5 = de;
    try
    {
        derived& base6 = dynamic_cast<derived &>(Base5);
        base6.show();
        cout << "转换成功" << endl;
    }
    catch (const std::exception& e)
    {
        cout << e.what() << endl;
    }
}