C++之智能指针类型转换应用总结(二百二十九)

2023-09-21 21:40:03

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长!

优质专栏:Audio工程师进阶系列原创干货持续更新中……】🚀

人生格言: 人生从来没有捷径,只有行动才是治疗恐惧和懒惰的唯一良药.

更多原创,欢迎关注:Android系统攻城狮

欢迎关注Android系统攻城狮

1.前言

本篇目的:理解C++之std::static_pointer_cast智能指针类型转换应用。

在C++中,std::static_pointer_cast是一种智能指针类型转换函数,用于将一个 std::shared_ptr 智能指针转换为另一种相关类型的智能指针。它的作用是在类型转换时保持智能指针的引用计数,确保资源的正确释放。

std::static_pointer_cast函数的用法如下所示:

std::shared_ptr<Derived> derivedPtr = std::static_pointer_cast<Derived>(basePtr);

其中Derived是目标类型,basePtr是指向基类类型的std::shared_ptr智能指针。该函数将basePtr转换为Derived类型的智能指针derivedPtr

std::static_pointer_cast的原理是使用了C++中的RTTI(Run-Time Type Information)机制,通过检查指针指向的对象的实际类型,并进行相应的类型转换操作。

std::static_pointer_cast通常用在需要将基类类型的智能指针转换为派生类类型的智能指针的场合。它可以方便地进行基类指针到派生类指针的安全转换,同时保持智能指针的引用计数,避免资源泄漏和多次释放的问题。

2.应用实例

v1.0 派生类指针向基类指针的转换

#include <iostream>
#include <memory>

class Base {
public:
    virtual void print() {
        std::cout << "Base" << std::endl;
    }
};

class Derived : public Base {
public:
    void print() override {
        std::cout << "Derived" << std::endl;
    }
};

int main() {
    std::shared_ptr<Derived> derivedPtr = std::make_shared<Derived>();
    std::shared_ptr<Base> basePtr = std::static_pointer_cast<Base>(derivedPtr);

    basePtr->print(); // 输出: Derived

    return 0;
}
  • 注意使用std::static_pointer_cast将派生类Derived转换成基类Base。

v2.0 将基类指针转换为派生类指针

#include <iostream>
#include <memory>

class Base {
public:
    virtual void print() {
        std::cout << "Base" << std::endl;
    }
};

class Derived : public Base {
public:
    void print() override {
        std::cout << "Derived" << std::endl;
    }
};

int main() {
    std::shared_ptr<Base> basePtr = std::make_shared<Derived>();
    std::shared_ptr<Derived> derivedPtr = std::static_pointer_cast<Derived>(basePtr);

    derivedPtr->print(); // 输出: Derived

    return 0;
}
  • 注意使用std::static_pointer_cast将基类Base转换成派生类Derived类型。

v3.0 将const指针转换为非const指针

#include <iostream>
#include <memory>

class Base {
public:
    void print() {
        std::cout << "Base" << std::endl;
    }
};

int main() {
    std::shared_ptr<const Base> constBasePtr = std::make_shared<const Base>();

    std::shared_ptr<Base> basePtr = std::const_pointer_cast<Base>(constBasePtr);
    basePtr->print(); // 输出: Base

    return 0;
}
  • 注意使用std::static_pointer_cast将基类Base转换成基类Derived类型

v4.0 将shared_ptr转换为weak_ptr

#include <iostream>
#include <memory>

class Base {
public:
    void print() {
        std::cout << "Base" << std::endl;
    }
};

int main() {
    std::shared_ptr<Base> basePtr = std::make_shared<Base>();

    std::weak_ptr<Base> weakBasePtr = std::static_pointer_cast<std::weak_ptr<Base>>(basePtr.lock());

    std::shared_ptr<Base> sharedBasePtr = weakBasePtr.lock();
    sharedBasePtr->print(); // 输出: Base

    return 0;
}
  • 注意使用std::static_pointer_cast将基类shared_ptr转换成基类weak_ptr类型

v5.0 将shared_ptr转换为unique_ptr

#include <iostream>
#include <memory>

class Base {
public:
    void print() {
        std::cout << "Base" << std::endl;
    }
};

int main() {
    std::shared_ptr<Base> basePtr = std::make_shared<Base>();

    std::unique_ptr<Base> uniqueBasePtr = std::static_pointer_cast<std::unique_ptr<Base>>(std::move(basePtr));

    uniqueBasePtr->print(); // 输出: Base

    return 0;
}
  • 注意使用std::static_pointer_cast将基类shared_ptr转换成基类unique_ptr类型

v6.0 将shared_ptr转换为shared_ptr的基类

#include <iostream>
#include <memory>

class Base {
public:
    virtual void print() {
        std::cout << "Base" << std::endl;
    }
};

class Derived : public Base {
public:
    void print() override {
        std::cout << "Derived" << std::endl;
    }
};

int main() {
    std::shared_ptr<Derived> derivedPtr = std::make_shared<Derived>();
    std::shared_ptr<Base> basePtr = std::static_pointer_cast<Base>(derivedPtr);

    basePtr->print(); // 输出: Derived

    std::shared_ptr<Derived> derivedPtr2 = std::static_pointer_cast<Derived>(basePtr);
    derivedPtr2->print(); // 输出: Derived

    return 0;
}
  • 注意使用std::static_pointer_cast将shared_ptr转换类shared_ptr基类。

v7.0 多重继承中的指针转换

#include <iostream>
#include <memory>

class Base1 {
public:
    virtual void print() {
        std::cout << "Base1" << std::endl;
    }
};

class Base2 {
public:
    virtual void print() {
        std::cout <<"Base2" << std::endl;
    }
};

class Derived : public Base1, public Base2 {
public:
    void print() override {
        std::cout << "Derived" << std::endl;
    }
};

int main() {
    std::shared_ptr<Derived> derivedPtr = std::make_shared<Derived>();

    std::shared_ptr<Base1> base1Ptr = std::static_pointer_cast<Base1>(derivedPtr);
    base1Ptr->print(); // 输出: Derived

    std::shared_ptr<Base2> base2Ptr = std::static_pointer_cast<Base2>(derivedPtr);
    base2Ptr->print(); // 输出: Derived

    return 0;
}
  • 注意使用std::static_pointer_cast将派生类Derived转换基类Base1,再转换成Base2类型。
更多推荐

QT Day2

Second.h#ifndefSECOND_H#defineSECOND_H#include<QWidget>namespaceUi{classSecond;}classSecond:publicQWidget{Q_OBJECTpublicslots:voidjump_slot();//接收跳转信号的槽函数public

Matter 协议系列:发现

Commissionable发现Commissionable发现发生在投入使用(未绑定)之前,指的是发现和识别Commissionable节点的过程。有三种方法可以通过这些方法中的任何一种来广播Commissionable的节点:蓝牙低功耗(BLE)Wi-FiSoft-AP基于IP的网络上的DNS-SD,也称为现有的I

laravel框架 - 集合篇

LaravelEloquent通常返回一个集合作为结果,集合包含很多有用的、功能强大的方法。你可以很方便的对集合进行过滤、修改等操作。本次教程就一起来看一看集合的常用方法及功能。你可以使用助手函数collect将数组转化为集合。$data=collect([1,2,3]);1.增加$data=collect([1,2,

Linux下进度条程序实现以及自动化构建工具makefile的实现和对回车键的理解

在实现进度条之前我们要了解一些有关实现进度条的知识。例如回车和makefile的使用自动化构建工具:makefilemakefile实现的目的就是可以进行自动化的编译与自动化清理,即实现好了makefile之后,仅仅使用make指令就可以直接完成程序的编译过程。先看一看咱们实现makefile之后得到的效果截图:这里m

Linux Day16 多线程的一些常见问题

目录一、多线程+fork()问题一:多线程中某个线程调用fork(),子进程会有和父进程相同数量的线程吗?1.1.1不使用fork前,让线程函数和主程序打印其进程号结果:结论:1.1.2在主程序中加入fork结果:结论:1.1.3线程函数加入fork()结果:结论:综上所述:多线程程序fork后,子进程只启用一条执行路

C++ 4种智能指针的定义与使用——学习记录008

1.智能指针1.1作用智能管理动态分配的内存,自动释放程序员new出来的内存,从而避免内存泄漏。1.2原理动态分配的内存交给有生命周期的对象处理,在对象过期时,内存的释放交给对象来处理。1.3使用方法#include<memory>auto_ptr<类型>变量名称(new类型);auto_ptr<string>str(

搜索引擎排名因素有哪些具体的细节?

搜索引擎排名因素有很多,以下是一些常见的因素:关键词密度和位置:搜索引擎会考虑关键词在网页上的出现频率和位置。关键词密度指的是关键词在网页内容中出现的频率与整个文本的比例。关键词的位置也很重要,例如,如果关键词出现在页面的顶部或标题标签中,则更有可能被搜索引擎重视。页面标题和元标签:这是搜索引擎对网页进行排名的关键因素

Observability:检测 OpenTelemetry 的推荐指南

作者:BahubaliShettiOpenTelemetry(OTel)正在稳步获得广泛的行业采用。作为主要的云原生计算基金会(CNCF)项目之一,其提交数量与Kubernetes一样多,它正在获得主要ISV和云提供商的支持,为该框架提供支持。许多来自金融、保险、科技和其他行业的全球公司开始对OpenTelemetry

Java -【字符串,数组,哈希表】常用操作

一.字符串创建字符串:可以使用双引号或者String类的构造方法创建字符串。Stringstr1="HelloWorld";Stringstr2=newString("HelloWorld");连接字符串:可以使用加号或者String类的concat()方法连接字符串。Stringstr3=str1+str2;Stri

【Linux】常用工具(上)

Linux常用工具一、Linux软件包管理器yum1.软件包2.查看软件包3.安装/卸载软件4.yum其他指令的功能二、Linux编辑器-vim使用1.vim的基本概念2.vim的基本操作(1)光标移动(命令模式)(2)光标定位(命令模式)(3)复制粘贴撤销(命令模式)(4)其他操作(命令模式)(5)保存并退出(底行模

最新医疗界AI资讯,远程评估帕金森病症状的AI工具问世

原创|文BFT机器人1、AI模型快速评估,自动生成评估报告罗切斯特大学研究人员开发的一种人工智能工具可以帮助帕金森病患者在几分钟内远程评估其症状的严重程度。《npj数字医学》杂志上的一项研究介绍了这种新工具,它能让用户在网络摄像头前通过敲击手指10次,以0-4的等级来评估运动性能。医生通常会让患者执行简单的运动任务,以

热文推荐