C++的强制类型转换,除了继承自C语言的写法((目标类型)表达式)之外,还新增了4个关键字,分别是:static_castdynamic_castconst_castreinterpret_cast。用法:xxx_cast<目标类型>(表达式)。由于后两者的使用频率较少,尤其是reinterpret_cast的风险性很高,所以就不展开讲了。这里主要将static_castdynamic_cast

static_cast

解释

所谓static_cast,顾名思义,就是静态的转换,是在编译期间就能确定的转换。

主要用途

  1. 用于基本数据类型之间的转换。
#include <iostream>

using namespace std;

int main()
{
    float f = 5.67;
    auto i = static_cast<int>(f);
    cout << i << endl;  // 输出结果:5
    return 0;
}
  1. 用于有转换关系的类之间的转换。
#include <iostream>

using namespace std;

class Src
{
public:
    void foo()
    {
        cout << "This is Src" << endl;
    }
};

class Dest
{
public:
    /** 类型转换构造函数 */
    Dest(const Src &from)
    {
        cout << "Converting from Src to Dest" << endl;
    }

    void foo()
    {
        cout << "This is Dest" << endl;
    }
};

int main()
{
    Src src;
    auto dst = static_cast<Dest>(src);  // 输出结果:Converting from Src to Dest
    dst.foo();  // 输出结果:This is Dest
}
  1. 用于在类继承体系中指针或引用上行转换(即派生类到基类的转换)。如果用作下行转换(即基类到派生类的转换),由于不会动态的检查指针或引用是否真正指向派生类对象,因此不安全,要用到稍后要讲的dynamic_cast
#include <iostream>

using namespace std;

class Base
{
public:
    void foo()
    {
        cout << "This is Base" << endl;
    }
};

class Derived : public Base
{
public:
    void foo()
    {
        cout << "This is Derived" << endl;
    }
};

void test_upcast()
{
    Derived derived;
    Derived *pDerived = &derived;
    auto pBase = static_cast<Base *>(pDerived);
    pBase->foo();  // 输出结果:This is Base
}

void test_downcast()
{
    Base base;
    Base *pBase = &base;
    auto pDerived = static_cast<Derived *>(pBase);  // 不安全:pa并没有真正指向B类对象
    pDerived->foo();  // 输出结果:This is Derived。这里虽然输出了结果,但是不安全
}

int main()
{
    test_upcast();
    test_downcast();
    return 0;
}

dynamic_cast

解释

所谓dynamic_cast,顾名思义就是动态的转换,是一种能够在运行时检查安全性的转换。

使用条件:

  1. 源类型必须有虚函数。
  2. 只能转引用或指针。

主要用途

用于继承体系中的上行或下行转换。上行转换跟static_cast是一样的;下行转换会在运行时动态判断。如果转换失败,那么:

  1. 指针的转换会返回nullptr
  2. 引用的转换会抛出std::bad_cast异常
#include <iostream>

using namespace std;

class Base {
public:
    virtual void foo()
    {
        cout << "This is Base" << endl;
    }
};

class Derived : public Base {
public:
    void foo() override
    {
        cout << "This is Derived" << endl;
    }
};

/** Derived * -> Base * */
void test_upcast_ptr() {
    Derived derived;
    Derived *pDerived = &derived;
    auto base = dynamic_cast<Base *>(pDerived);
    if (base) {
        cout << "Derived * -> Base * was successful" << endl;
    } else {
        cout << "Derived * -> Base * failed" << endl;
    }
}

/** Base * -> Derived * */
void test_downcast_ptr1() {
    Derived derived;
    Base *pBase = &derived;
    auto pDerived = dynamic_cast<Derived *>(pBase);
    if (pDerived) {
        cout << "Base * -> Derived * was successful" << endl;
    } else {
        cout << "Base * -> Derived * failed" << endl;
    }
}

/** Base * -> Derived * */
void test_downcast_ptr2() {
    Base base;
    Base *pBase = &base;
    auto derived = dynamic_cast<Derived *>(pBase);
    if (derived) {
        cout << "Base * -> Derived * was successful" << endl;
    } else {
        cout << "Base * -> Derived * failed" << endl;
    }
}

/** Derived & -> Base & */
void test_upcast_ref() {
    Derived derived;
    Derived &refDerived = derived;
    try {
        auto &base = dynamic_cast<Base &>(refDerived);
        cout << "Derived & -> Base & was successful" << endl;
    } catch (bad_cast &) {
        cout << "Derived & -> Base & failed" << endl;
    }
}

/** Base & -> Derived & */
void test_downcast_ref1() {
    Derived derived;
    Base &refBase = derived;
    try {
        auto &refDerived = dynamic_cast<Derived &>(refBase);
        cout << "Base & -> Derived & was successful" << endl;
    } catch (bad_cast &) {
        cout << "Base & -> Derived & failed" << endl;
    }
}

/** Base & -> Derived & */
void test_downcast_ref2() {
    Base base;
    Base &refBase = base;
    try {
        auto &refDerived = dynamic_cast<Derived &>(refBase);
        cout << "Base & -> Derived & was successful" << endl;
    } catch (bad_cast &) {
        cout << "Base & -> Derived & failed" << endl;
    }
}

int main() {
    test_upcast_ptr();     // Derived * -> Base * was successful
    test_downcast_ptr1();  // Base * -> Derived * was successful
    test_downcast_ptr2();  // Base * -> Derived * failed
    test_upcast_ref();     // Derived & -> Base & was successful
    test_downcast_ref1();  // Base & -> Derived & was successful
    test_downcast_ref2();  // Base & -> Derived & failed
}
内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/YWT-Real/p/16717930.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!

相关课程