浅谈C++11四种cast类型转换

点击上方蓝字关注我,我们一起学编程
有任何疑问或者想看的内容,欢迎私信

今天我们来学习一下 C++ 中常用的类型转换

1. static_cast

static_cast 是将表达式转换为某种类型,语法是 T t = static_cast<T>(expression)。通常用于各种内置类型之间的隐式转换。

#include <iostream>
#include<typeinfo>

using namespace std;

int main() {
    double a = 1.23;

    auto b = static_cast<int>(a);

    cout << b << endl;                   // 1
    cout << typeid(b).name() << endl;    // i (i 表示 int)

    return 0;
}

在上面的示例中,为了更突出地说明问题,我们在用 auto 变量(类型自动推断)来保存转换后的结果,然后输出转换结果的类型。程序输出结果表示,类型转换成功。

2. const_cast

const_cast 可以修改类型的 const 或 volatile 属性。通常的用法是将常量转换成非常量,从而可以对这个常量进行修改。const_cast 的返回值是一个指向原变量的指针或引用。

#include <iostream>
#include<typeinfo>

using namespace std;

int main() {
    const int a = 1;

    auto b = const_cast<int*>(&a);
    auto c = const_cast<int&>(a);

    *b = 2;
    c = 3;
    cout << "b = " << *b << " c = " << c << endl;
    cout << "type of b is " << typeid(*b).name() << endl;
    cout << "type of c is " << typeid(c).name() << endl;

    return 0;
}

/*
运行结果:
b = 2 c = 3
type of b is i
type of c is i
*/

显然,转换后变量已经支持修改,即非常量。

3. dynamic_cast

dynamic_cast 用于动态类型转换,只能用于转换含有虚函数的类,用于类层次之间的向上(派生类向基类)和向下转换(基类向派生类)。只能转指针或引用,如果是非法的转换,对于指针返回 NULL ,对于引用抛出异常。

之所以叫作动态类型转换,就是因为它通过判断在执行到该语句的时候,变量的运行时类型来进行转换的。

#include <iostream>

using namespace std;

class Fruit {
public:
    virtual void show() {
        cout << "I am fruit" << endl;
    }
};

class Apple : public Fruit {
public:
    void show() {
        cout << "I am apple" << endl;
    }
};

class Banana : public Fruit {
public:
    void show() {
        cout << "I am banana" << endl;
    }
};

int main() {
    Fruit f;
    Apple a;
    Banana b;

    // 转换成功

    Fruit* pf1 = dynamic_cast<Fruit*>(&a);
    a.show();               // I am apple
    pf1->show();            // I am apple
    cout << &a << endl;     // 0x7ffe3298d910
    cout << pf1 << endl;    // 0x7ffe3298d910

    Fruit* pf2 = dynamic_cast<Fruit*>(&b);
    b.show();               // I am banana
    pf2->show();            // I am banana
    cout << &b << endl;     // 0x7ffe3298d908
    cout << pf2 << endl;    // 0x7ffe3298d908

    // 转换失败

    Apple* pa = dynamic_cast<Apple*>(&b);
    cout << &b << endl;     // 0x7ffe3298d908
    cout << pa << endl;     // 0

    Banana& pb = dynamic_cast<Banana&>(a);    // terminate called after throwing an instance of 'std::bad_cast'
}

通过示例我们可以看出,基类和派生类之间可以相互转换,但同一基类的不同派生类 (Apple 和 Banana) 之间是不能成功转换的。

4. reinterpret_cast

reinterpret_cast 是用来处理无关类型之间的转换。reinterpret_cast 几乎可以转换任意类型,但是很容易出问题,我们尽量不要使用。这里我也不准备花很多篇幅去讲解这个转换,下面用一个例子一笔带过:将一个整数类型转换成指针类型。

#include <iostream>

using namespace std;

int main() {
    int a  = 1;
    int* pa = &a;
    long long int b = reinterpret_cast<long long int>(pa);
    
    cout << "pa = " << pa << endl;
    cout << "b =  " << b << endl;

    int* c = reinterpret_cast<int*>(b);
    
    cout << "c =  " << c << endl;
}

/*
运行结果:
pa = 0x7ffe325c49c4
b =  140729743329732
c =  0x7ffe325c49c4
*/

从上面的示例可以看出,我们先将一个指针转换成一个整数,在将这个整数转换成指针,发现两次的指针是相同的。

点击下方图片关注我,或微信搜索**“编程笔记本”**,获取更多信息。

发布了19 篇原创文章 · 获赞 0 · 访问量 200
展开阅读全文
评论将由博主筛选后显示,对所有人可见 | 还能输入1000个字符

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览