首页 > 编程语言 >C++11 四种强制类型转换的区别

C++11 四种强制类型转换的区别

时间:2023-08-24 20:35:36浏览次数:32  
标签:11 类型转换 dynamic C++ cast shared pointer ptr 指针

static_cast: 指针强转, 如果某个基类有多个子类, 基类的指针实际是指向A类的对象, 但使用强转为B类对象, 运行时会报错, 静态强转没做检测
dynamic_cast: 只能用于虚函数类, 子类与父类指针互转, 会检测, 转换失败为返回空, 不会崩
const_cast: 用于转换常量, 修改常量, 先用一个常量指针指向原来常量, 再用const_cast把这个常量指针转为普通指针, 再修改值(后面只能指针)
reinterpret_cast: 重新解释, 一个类继续于多个父类, 每个父类都一个相同名字的函数, 调用时系统不知道调用哪个函数, 可以使用重新解释为某个父类指针(后面指针)
static_pointer_cast,dynamic_pointer_cast,const_pointer_cast,reinterpret_pointer_cast 这四个宏转对象上面4种但转为shared_ptr

#include <iostream>
using namespace std;

class BaseClass
{
public:
    virtual void Action()
    {
        cout << "BaseClass Action!\n";
    }
};

class ChildClass : public BaseClass
{
public:
    ChildClass() {};
    ChildClass(int a) { age = a; }
    virtual void Action() override
    {
        cout << "ChildClass Action!\n";
    }
    int age;
};

class ThirdClass
{

};
class Union
{
public:
    void Say() {cout << "Union'Say\n";}
};

class Bag
{
public:
    void Say() { cout << "Bag'Say\n"; }
};

class Player : public Union, Bag
{
public:
    void Say() { cout << "Player'Say\n"; }
};

/// <summary>
/// 总结:
/// static_cast: 指针强转, 如果某个基类有多个子类, 基类的指针实际是指向A类的对象, 但使用强转为B类对象, 运行时会报错, 静态强转没做检测
/// dynamic_cast: 只能用于虚函数类, 子类与父类指针互转, 会检测, 转换失败为返回空, 不会崩
/// const_cast: 用于转换常量, 修改常量, 先用一个常量指针指向原来常量, 再用const_cast把这个常量指针转为普通指针, 再修改值(后面只能指针)
/// reinterpret_cast: 重新解释, 一个类继续于多个父类, 每个父类都一个相同名字的函数, 调用时系统不知道调用哪个函数, 可以使用重新解释为某个父类指针(后面指针)
/// static_pointer_cast,dynamic_pointer_cast,const_pointer_cast,reinterpret_pointer_cast 这四个宏转对象上面4种但转为shared_ptr
/// </summary>
/// <returns></returns>
int main()
{
    //static_pointer_cast与dynamic_pointer_cast测试
    shared_ptr<ChildClass> ptrChildClass = make_shared<ChildClass>();
    //shared_ptr<BaseClass> ptrClass = make_shared<ChildClass>(); //报错, 不能这样写
    //shared_ptr<BaseClass> ptrClass = (shared_ptr<BaseClass>*)make_shared<ChildClass>(); //报错, 不支持
    //shared_ptr<ChildClass> ptr = dynamic_cast<ChildClass>(ptrChildClass); // 报错 dynamic_cast是用来转换new之类的指针的
    //shared_ptr<ChildClass> ptr = dynamic_pointer_cast<ChildClass>(ptrChildClass);
        shared_ptr<BaseClass> ptrParent = dynamic_pointer_cast<BaseClass>(ptrChildClass); //子类转父类的指针
    ptrParent->Action();

    shared_ptr<ChildClass> ptrChildClass2 = static_pointer_cast<ChildClass>(ptrParent); //父类转向子类的指针
    ptrChildClass2->Action();

    //动态转换失败会返回空, 静态这儿是编译不过(可能其它编译器编译过, 运行也会崩的)
    shared_ptr<ThirdClass> ptrThird = dynamic_pointer_cast<ThirdClass>(ptrParent);
    if (!ptrThird)
    {
        cout << "ptrThird is nullptr" << endl;
    }

    //const_cast测试 先用一个常量指针指向原常量, 然后用const_cast把常量指针转成普通指针, 再修改原数据
    const ChildClass child(4);
    //child.age = 5; //修改不了
    cout << child.age << endl;
    const ChildClass* pChild = &child;
    //pChild->age = 5; //修改不了
    ChildClass* tmp = const_cast<ChildClass*>(pChild);
    tmp->age = 3;
    cout << child.age << endl;


    const int a = 10;
    const int* p = &a;
    int* q;
    q = const_cast<int*>(p);
    *q = 20;    //fine
    cout << a << " " << *p << " " << *q << endl;
    cout << &a << " " << p << " " << q << endl;
    
    //reinterpret_cast测试
    Player player;
    player.Say();
    // auto bag = reinterpret_cast<Bag>(player); //编译不过, 提示出错
    // Bag b = (Bag)(player);//编译出错    
    Bag* b = (Bag*)(&player); //C式强转
    b->Say();

    auto myunion = reinterpret_cast<Union*>(&player); //重解释
    myunion->Say();
    system("pause");
    return 0;
}

 

参考1:https://blog.csdn.net/qq_21989927/article/details/111226696

参考2:https://blog.csdn.net/sunlin972913894/article/details/108427587

标签:11,类型转换,dynamic,C++,cast,shared,pointer,ptr,指针
From: https://www.cnblogs.com/barrysgy/p/17655089.html

相关文章

  • C++拷贝构造、赋值函数
    拷贝构造拷贝构造就是一种特殊版本的构造函数,格式:类名(const类名&that){    //执行给每个成员变量进行赋值  }什么时候会调用拷贝构造:当使用旧对象(已new的)给新对象(新new的)初始化时,会自动调用拷贝构造    Testt1;//调用无参构造Testt2=t1......
  • C++this指针、常函数
    this指针this指针的类型:类类型*const。不能被修改和赋值。只能在成员函数的内部使用。全局函数、静态函数都不能使用this.this指针本质上其实是一个成员函数的形参(栈),是对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。this指针是成......
  • C++静态成员和单例模式
    一、静态成员Ⅰ.什么是静态成员:被static修饰的成员变量和成员函数就叫静态成员Ⅱ.普通成员的特点:成员变量:每个类对象中都有一份属于自己的成员变量,相互之间没有关联、独立的成员函数:隐藏着一个this指针,接收调用者的地址用于区分调用者Ⅲ.静态成员的特点:静态成员变......
  • C++对象的创建和销毁过程分析
    对象的创建和销毁过程分析1、对象的创建过程①给对象划分内存空间(栈、堆)②执行初始化列表根据继承表的顺序调用父类的无参构造或有参构造通过:父类(val)调用父类的有参构造根据成员变量的定义顺序调用类类型成员的无参构造或有参构造通过:类类型成员名(val)调用类类型成员......
  • C++面向对象、类和对象、访问控制限定符
    面向对象和面向过程面向过程:关注如何解决问题,以及解决问题的步骤面向对象:关注的解决问题的"人"即"对象",以及实现能解决问题的"对象"注意:面向对象的细节的本质上还是面向过程,因此面向对象不是解决问题的捷径,而是以更高的维度去思考问题面向对象的四个特性:抽象:先找出(想象)......
  • Windows中通过C++自动添加防火墙例外规则
    在C++程序中无法直接控制防火墙警报窗口的显示,因为这是由操作系统和防火墙软件控制的。防火墙警报窗口是为了提醒用户程序正在尝试与外部网络进行通信,以确保用户意识到可能的网络活动。然而,可以通过编写C++程序在用户的系统上自动添加防火墙例外规则,从而避免防火墙警报窗口的显示......
  • 快手Java一面11问(附参考答案)
    现在已经到了面试招聘比较火热的时候,后续会分享一些面试真题供大家复习参考。准备面试的过程中,一定要多看面经,多自测!今天分享的是一位贵州大学的同学分享的快手一面面经。快手一面主要会问一些基础问题,也就是比较简单且容易准备的常规八股,通常不会问项目。到了二面,会开始问项目,......
  • windows 桌面GUI自动化- 11.pywinauto 窗口和控件截图capture_as_image()
    前言pywinauto对窗口和控件截图capture_as_image()窗口截图对连接的窗口截图frompywinautoimportApplicationapp=Application('uia').start("notepad.exe")win=app.window(title_re="无标题-记事本")#对窗口截图win.capture_as_image().save('not.pn......
  • C++构造函数、析构函数、初始化列表
    构造函数构造函数就是与类名同名的成员函数,当实例化对象时它会自动执行,当构造函数执行结束后,对象才完成实例化任务:一般负责对类对象进行初始化、资源分配class类名{int*p;public:类名(参数){p=newint;}}......
  • 20230711 java.security.MessageDigest
    介绍java.security.MessageDigestpublicabstractclassMessageDigestextendsMessageDigestSpiAPIstaticgetInstanceMessageDigestgetInstance(Stringalgorithm)throwsNoSuchAlgorithmExceptionMessageDigestgetInstance(Stringalgorithm,Stringprovider)......