首页 > 编程语言 >UEC++ 智能指针——共享指针、共享引用、弱指针

UEC++ 智能指针——共享指针、共享引用、弱指针

时间:2022-09-23 13:11:18浏览次数:49  
标签:对象 C++ 内存 共享 指针 Ftc02 引用

C++中,往往令人头痛的是指针的管理问题!在对象动态构建时,我们需要将对象指针进行存储,一旦忘记释放,那么将会导致不可预估的错误。在C++中排查指针导致的内存泄漏问题实在令人头痛!在虚幻中,为了解决此类问题,加入了智能指针(共享指针,共享引用,弱指针),当我们使用动态方式构建对象时,再也不需要担心内存释放问题!指针的释放规则由引擎制定,包括释放时机!

1、自定义类

在构建自定义类时,我们经常遇到一种情况,当类中持有U类对象指针时,我们希望阻止垃圾回收器对对象释放。但是自定义类中又无法使用UPROPERTY宏,那么我们可以采取将类继承自FGCObject,并重写父类函数AddReferencedObjects。将需要阻止释放的指针加入到操作队列,以防止对象被垃圾回收器回收!

注意:当构建类被释放时(需要我们保证),并且调用其析构函数(析构函数需要重写父类析构函数),对象将自动清除其所添加的所有引用。

2、智能指针

  • 虚幻中存在一套非常强大的动态内存管理机制,而这套机制中根本在于智能指针(非侵入式),并且UE的智能指针速度相比STL更快,速度和普通C++指针速度一样。
  • 智能指针本质的目的是将释放内存工作进行托管。当两个智能指针指向同一个空间,一个设置为空,另一个不会跟随为空,智能指针设置为空并不是释放内存空间,只是在减少空间引用。

注意:智能指针只能使用于自定义类,U类禁止使用

共享指针和共享引用的优点:

三个指针

 3、共享指针

共享指针是虚幻中最常用的智能指针,在操作上可以帮助我们构建托管内存指针!共享指针本身非侵入式的,这使得指针的使用与操作和普通指针一致!共享指针支持主动指向空,并且共享指针是线程安全的,节省内存,性能高效

注意:构建自定义类时,需要使用 F 开头

 

 基本操作语法:

// 自定义类
class MX_API FTestClass
{
public:
    FTestClass();
    ~FTestClass();

    void TestFun();
};
    
   // 其他类
  // 构建一个共享指针,但是没有维护任何空间 TSharedPtr<FTestClass> Ftc01;// 不推荐 // 构建一个共享指针,并维护一快内存 TSharedPtr<FTestClass> Ftc02(new FTestClass()); //MakeShareable函数是用来构建共享指针的快捷方式 // 构建一个共享指针,并维护一快内存 TSharedPtr<FTestClass> Ftc03 = MakeShareable(new FTestClass()); // 解引用和操作 Ftc02->TestFun(); Ftc02.Get()->TestFun(); (*Ftc02).TestFun(); // 比较两个智能管理的内存是否是同一个 if (Ftc02 == Ftc03) {} // 判断是否为空 注意操作函数是共享指针的成员函数 if (Ftc02.IsValid()) {} // 注意操作函数是共享指针的成员函数 if (Ftc02.Get() == nullptr) {} // 获取引用计时器 获得当前地址被引用个数 Ftc02.GetSharedReferenceCount(); // 释放 Ftc02.Reset(); Ftc03 = nullptr;

 4、共享引用

  • 共享引用禁止为空,表明了共享引用创建后必须给予有效初始化,可以使得代码更加安全简洁,保证了对象访问的安全性。无法主动释放共享引用,可以跟随对象释放减少引用计数器
  • 共享引用的安全性体现在,如果使用共享引用构建的对象,无法将对象空间设置为空。如果想释放内存,可以借助指向其他共享引用来减少引用计数,来释放空间
  • 共享引用本质,无法主动减少引用计数器,只能通过被动方法,例如生命周期终结,共享引用易主

基本语法操作

    // 定义
    TSharedRef<FTestClass> Ftc01;// 错误执行将导致崩溃
    TSharedRef<FTestClass> Ftc02(new FTestClass);// 正确
    // 解引用操作
    Ftc02->TestFun();
    (*Ftc02).TestFun();
    // 返回cosnt 引用 ,禁止将对象主动释放
    const FTestClass& Ftc03 = Ftc02.Get();
    // 和共享指针转换
    // 共享引用支持隐式转换为共享指针,由于共享引用是安全的,所以转换是隐式转换
    TSharedPtr<FTestClass> Ftc04 = Ftc02;
    // 从共享指针转换到共享引用是不安全的,所以需要调用TS函数
    TSharedRef<FTestClass> Ftc05 = Ftc04.ToSharedRef();

5、弱指针

  • 不会阻止对象的销毁,如果引用对象被销毁,则弱指针也将自动清空。一般弱指针的操作意图是保存了一个到达目标对象的指针,担不会控制该对象的生命周期,弱指针不会增加引用计数,可以用来断开引用循环问题。 、
  • 无论谁销毁了对象,只要其对象被销毁,弱指针都将自动清空,这使你能够安全缓存指向可变对象的指针。这也意味着,弱指针可能会意外清空,并且,你可以使用弱指针断开引用循环。
  • 当不再存在对对象的共享引用时,弱指针的对象将被销毁。
  • 弱指针有助于表明意图。当你在某个类中看到一个弱指针时,你就会明白该类仅缓存指向对象的指针,它并不控制它的生命周期。

基本语法操作

    // 定义
    // 构建空的弱指针
    TWeakPtr<FTestClass> WpFtc01;
    // 利用共享指针构建弱指针
    TSharedPtr<FTestClass> PFtc;
    TWeakPtr<FTestClass> WpFtc02(PFtc);
    // 利用共享引用构建弱指针
    TSharedRef<FTestClass> RFtc;
    TWeakPtr<FTestClass> WpFtc03(RFtc);
    // 检查是否有效
    // 检查弱指针指向的对象空间是否存在
    if (WpFtc01.IsValid()) {}
    // 释放操作
    // 主动释放,但是不会影响引用计数
    WpFtc01 = nullptr;

总结

  • 一块内存,如果存在有效引用(可直接到达内存的操作方式),则我们可以认为当前内存是有效并且合理的!但是当一块内存不存在引用,则我们可以视为此块内存为被弃用无效的,则可以回收重复利用,这就是内存垃圾回收机制的基本原理。
  • 智能指针强调的是当前内存的使用者存在多少,当不存在时,进行回收!
  • 注意:智能指针构建的均是栈对象数据类型

 

标签:对象,C++,内存,共享,指针,Ftc02,引用
From: https://www.cnblogs.com/limu-zy/p/16722326.html

相关文章

  • 小程序共享数据2 - 代码实例
    import{HYEventStore}from"hy-event-store"import{getPlaylistDetail}from"../services/music"constrecommendStore=newHYEventStore({state:{......
  • 【C++入门】(六)高级引用和指针
    1.如何利用按引用传递来提高程序的效率1.1按引用传递以提高效率请看下面这段代码,体会精神classSimpleCat{public:SimpleCat();//构造函数......
  • 【C++入门】(三)创建指针
    1.指针是什么?1.1理解指针及其用途变量是可存储一个值的对象:整型变量存储一个数字;字符变量存储一个字母;指针是存储内存地址的变量计算机内存是存储变量......
  • 【C++入门】(四)开发高级指针
    1.如何在堆中创建对象?1.1在堆中创建对象定义了类型Cat后,便可声明一个指向这种对象的指针,并在堆中实例化一个Cat对象,就像在栈中实例化一样Cat*pCat=newCat;......
  • 小程序共享数据 - 代码实例
    //1.引入storeconst{HYEventStore}=require("hy-event-store")//引入axiosconstaxios=require("axios")//创建一个仓库constuserStore=newHYEventSt......
  • 【C++入门】(一)创建基本类
    1.类型是是什么?类型是一个包含数据和功能的对象 2.什么是类和对象?C++类是一个模板,用于创建对象。类是一系列捆绑在一起的变量和函数,变量构成了类的数据,......
  • C++ "链链"不忘@必有回响之双向链表
    C++"链链"不忘@必有回响之双向链表1.前言写过一篇与单链表相关的博文(https://blog.51cto.com/gkcode/5681771),实际应用中,双向循环链表的功能更强大。单链表中,查询一个......
  • DSC共享存储集群的搭建
    首先进行环境准备硬件:两台相同配置机器,3G内存,23G本地磁盘,2块网卡,另有一块共享磁盘20G。操作系统:Ubuntu64位。DM各种工具位于目录:/dm8/tool。配置文件位于目录:/dm8/da......
  • 「浙江理工大学ACM入队200题系列」问题 A: 零基础学C/C++34—— 3个数比较大小(冒泡排
    深夜写的,代码都还没来得及跑一便,可能有错误,欢迎指出,后续会检验一遍并修改错误.本题是浙江理工大学ACM入队200题第四套中的A题,同时给出了冒泡排序和选择排序算法......
  • 从汇编看C++函数返回对象
    同样的代码,在msvc和gcc里面实现不同。structTest{inta;intb;intc;intd;~Test(){std::cout<<"end"<<std::endl;}};TestgetTest(){Testsa;sa.a=1......