设为首页 加入收藏

TOP

static_cast和dynamic_cast(一)
2023-07-23 13:30:58 】 浏览:65
Tags:static_cast dynamic_cast

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 <
首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇【C++】初始化列表构造函数VS普通.. 下一篇【C++】requires关键字简介

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目