C++11新特性之四种类型转换cast说明

 更新时间:2023年02月09日 13:01:55   作者:面条有点辣  
类型转换是项目中常使用的一种语法规则,几乎每个编程语言都不可避免的涉及到这方面,下面这篇文章主要给大家介绍了关于C++11新特性之四种类型转换cast说明的相关资料,需要的朋友可以参考下

引言

C++11引入了四种类型转换接口,它们分别是static_cast、const_cast、dynamic_cast、reinterpret_cast。

为什么要使用这四种转换呢?

给出面向对象编程和面向对象设计的五个基本原则,SOLID原则。

  • Single Responsibility Principle:单一职责原则
  • Open Closed Principle:开闭原则
  • Liskov Substitution Principle:里氏替换原则
  • Law of Demeter:迪米特法则
  • Interface Segregation Principle:接口隔离原则
  • Dependence Inversion Principle:依赖倒置原则

这里不详细叙述五个基本原则,我们使用的cast接口和里氏替换原则有关。

里氏替换原则: “派生类(子类)对象可以在程式中代替其基类(超类)对象。” 以上内容并非利斯科夫的原文,而是译自罗伯特·马丁(Robert Martin)对原文的解读[1]

1、static_cast

1.1 基本类型转换

1.2 类的上行转换(安全)

用于子类指针或引用转换为父类指针或引用。

#include <iostream>
using namespace std;

class Base
{
public:
    Base() {};
    virtual void Show() { cout << "This is Base class"; }
};
class Derived :public Base
{
public:
    Derived() {};
    void Show() { cout << "This is Derived class"; }
};
int main()
{
    Derived* der = new Derived;
    auto  Derived = static_cast<Base*> (der);
    //向上转换一直是安全的
    Derived->Show();
    system("pause");
}

输出结果为

This is Derived class

存在虚函数重载,则父类的函数被隐藏不能使用。

由于使用dynamic_caststatic_cast方法会存在开销,则一般使用下列方法进行向上转换。

class Base
{
public:
    Base(){};
    virtual void Show(){cout<<"This is Base class";}
};
class Derived:public Base
{
public:
    Derived(){};
    void Show(){cout<<"This is Derived class";}
};
int main()
{
    Base *base ;
    Derived *der = new Derived;
    //向上转换总是安全
    base = der; 
    base->Show();
    system("pause");
}

1.3 类的下行转换(不安全)

将父类指针、引用转换为子类指针、引用,但需要程序员自己检查,因此这种转换方式也不存在额外的开销。

2、const_cast

2.1 改变常量属性

  • 常量指针转化为非常量指针;
  • 常量引用转化为非常量引用;
  • 常量对象转化为非常量对象

3、dynamic_cast

该转换是运行时转换,其余都是编译时转换。主要用于安全的向下进行转换。同时当指针是智能指针时,使用dynamic_cast向下转换不能成功,需使用dynamic_point_cast来进行转换。

3.1 类的上行转换(安全)

此处和static_cast是一样的,不再过多叙述。

#include <iostream>
using namespace std;

class Base
{
public:
    Base() {};
    virtual void Show() { cout << "This is Base calss"; }
};
class Derived :public Base
{
public:
    Derived() {};
    void Show() { cout << "This is Derived class"; }
};
int main()
{
    Derived* der = new Derived;
    auto  Derived = dynamic_cast<Base*> (der);
    //向上转换一直是安全的
    Derived->Show();
    system("pause");
}

3.2 类的下行转换(安全)

因为有类型检查所以是安全的,但类型检查需要运行时类型信息,这个信息位于虚函数表中,所以必须要有虚函数,否则会转换失败。
在dynamic_cast转换中分为两种情况。

1、当基类指针指向派生对象时能够安全转换。

2、基类指针指向基类时会做检查,转换失败,返回结果0。

#include <iostream>
using namespace std;

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;
    Derived* der = dynamic_cast<Derived*>(base);
    //基类指针指向派生类对象时能够安全转换
    der->Show();
    //第二种情况
    Base *base1 = new Base;

    if (Derived* der1 = dynamic_cast<Derived*> (base1))
    {
        der1->Show();
    }
    else
    {
        cout << "error!";
    }
    delete(base);
    delete(base1);
    system("pause");
}

This is Derived class
error!

引用则和指针不同,指针在C++11中存在空指针,而引用不存在空引用,会引发bad_cast异常。

#include <iostream>
using namespace std;

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()
{
    //基类引用子类
    Derived b;
    Base& base1 = b;
    Derived& der1 = dynamic_cast<Derived&>(base1);
    der1.Show();

    //基类引用基类
    Base a;
    Base& base2 = a;
    try
    {
        Derived& der2 = dynamic_cast<Derived&>(base2);
    }
    catch(bad_cast)
    {
        cout << "bad_cast error!!" << endl;
    }
    system("pause");
}

This is Derived class
bad_cast error!!

4、reinterpret_cast

4.1 非关联类型的转换

操作结果是一个指针到其他指针的二进制拷贝,没有类型检查。

总结

到此这篇关于C++11新特性之四种类型转换cast说明的文章就介绍到这了,更多相关C++11类型转换cast内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言实现哈希搜索算法及原理详解

    C语言实现哈希搜索算法及原理详解

    本文主要介绍了C语言实现哈希搜索算法及原理详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-06-06
  • C++实现猴子吃桃的示例代码

    C++实现猴子吃桃的示例代码

    这篇文章主要介绍了C++实现猴子吃桃的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • C语言技巧提升之回调函数的掌握

    C语言技巧提升之回调函数的掌握

    这篇文章主要为大家详细介绍一下C语言中回调函数的用法教程,文中的示例代码讲解详细,对我们学习C语言有一定帮助,需要的可以参考一下
    2022-12-12
  • C++数据结构之链表详解

    C++数据结构之链表详解

    这篇文章主要介绍了C++数据结构之链表的创建的相关资料,希望通过本文帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下
    2021-08-08
  • 一篇文章带你了解C语言函数的可重入性

    一篇文章带你了解C语言函数的可重入性

    这篇文章主要为大家详细介绍了C语言函数的可重入性,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-08-08
  • C++实现简单猜数字小游戏

    C++实现简单猜数字小游戏

    这篇文章主要为大家详细介绍了C++实现简单猜数字小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-01-01
  • C语言中位域的使用详解

    C语言中位域的使用详解

    位域是C语言中的一种高级功能,允许程序员为结构体的成员分配特定数量的位,本文主要为大家介绍了位域的使用以及优缺点,希望对大家有所帮助
    2023-07-07
  • Qt数据库应用之超级自定义委托

    Qt数据库应用之超级自定义委托

    Qt中需要用到自定义委托的情形很多,比如提供下拉框选择,进度条展示下载进度啥的,默认的单元格是没有这些效果的,需要自己单独用委托的形式来展示。本文将为大家介绍Qt中如何进行超级自定义委托,需要的可以参考一下
    2022-03-03
  • VC外部符号错误_main,_WinMain@16,__beginthreadex解决方法

    VC外部符号错误_main,_WinMain@16,__beginthreadex解决方法

    这篇文章主要介绍了VC外部符号错误_main,_WinMain@16,__beginthreadex解决方法,实例分析了比较典型的错误及对应的解决方法,需要的朋友可以参考下
    2015-05-05
  • VS Code C++环境的搭建过程

    VS Code C++环境的搭建过程

    这篇文章主要介绍了VS Code C++环境的搭建,Somasegar 也告诉笔者这款编辑器也拥有对 Git 的开箱即用的支持,需要的朋友可以参考下
    2022-04-04

最新评论