首页 > 编程语言 >C++ unique_ptr简单使用

C++ unique_ptr简单使用

时间:2023-12-22 16:56:27浏览次数:48  
标签:std C++ num printf unique ptr 指针

#######################智能指针(智能指针是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保在离开指针所在作用域时,自动正确的销毁动态分配的对象,防止内存泄漏)
头文件#include <memory>
unique_ptr特性 (属性为对象, 而不是指针, 管理指针)
(1).基于排他所有权模式:两个指针不能指向同一个资源
无法进行左值unique_ptr复制构造,也无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值
保存指向某个对象的指针,当它本身离开作用域时会自动释放它指向的对象。
在容器中保存指针是安全的
无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值, 结合std::move()使用, 将一个

(2). unique_ptr做为STL容器的元素时,不能作为类的成员变量; share_ptr可以作为类成员嵌套使用
例如:

class b{
private:
vector<unique_ptr<int>> temp; //错误
vector<unique_ptr<a>> tmp; //错误
}

(3). unique_ptr做为STL容器的元素时,不能直接进行传递,因为不可以进行拷贝和赋值操作.
vector<unique_ptr<int>> a;
a.push_back(new int(20)); //错误
a.emplace_back(new int(20)); //错误
a.emplace_back(make_unique<int>(20)); //错误

 


方法:
1. get(); // 返回对象管理的裸指针,带有风险性
2. release(); // 释放,调用后智能指针和其所指向对象的联系再无联系,但是该内存仍然存在有效。它会返回裸指针,但是该智能指针被置空。
返回的裸指针我们可以手工delete来释放,也可以用来初始化另外一个智能指针,或者给另外一个智能指针赋值。
3. reset();
reset()不带参数情况:释放智能指针所指向的对象(释放因为它是独占,而不像shared_ptr还需要考虑引用计数),并将智能指针置空。
reset()带参数时:释放智能指针所指向的对象,并将该智能指针指向新对象。

4. swap(); // 交换智能指针


例如:
unique_ptr<string> pointer(new string("123456"));
unique_ptr<string> pointer2(new string("888888"));

pointer = pointer2; // 非法, 禁止左值赋值操作
unique_ptr<string> pointer3(pointer2); // 禁止左值赋值构造

unique_ptr<string> p3(std::move(p1)); // 合法, std::move()将左值改变成右值
p1 = std::move(p2); // 使用move把左值转成右值就可以赋值了,效果和auto_ptr赋值一样

简单代码例子:

#include <iostream>
#include <string>
#include <memory>
#include <stdio.h>
#include <stdlib.h>
#include <vector>

using namespace std;

class Absobj
{
public:
    Absobj()
    {
        printf("Create Abs - address: %p\n", this);
    }

    void print()
    {
        printf("Absobj print------\n");
    }

    ~Absobj()
    {
        printf("~Del AbsObj - address: %p\n", this);
    }

    char *pBuf = nullptr;
    int m_num = 0;
};


unique_ptr<Absobj> createPoint(int num)
{
    unique_ptr<Absobj> ptr(new Absobj);
    printf("ptr: %p\n", &ptr);
    ptr->m_num = num;
    return ptr;
}

void dowork(std::unique_ptr<Absobj> &&ptr)
{
    printf("ptr: %d\n", ptr->m_num);
    ptr->m_num = 888;
}

void gowork(std::unique_ptr<Absobj> ptr)
{
    printf("-->ptr: %d\n", ptr->m_num);
}

void towork(std::unique_ptr<Absobj> &ptr)
{
    printf(">>>ptr: %d\n", ptr->m_num);
}

int main(void)
{
    vector<unique_ptr<Absobj>> vec;

    unique_ptr<Absobj> ptr(new Absobj);
    ptr->m_num = 123;
    printf("ptr address: %p | num: %d\n", &ptr, ptr->m_num);

    dowork(std::move(ptr));         // 二级引用做参数,操作的是本身,std::move不会释放智能指针对象
    if ( ptr == nullptr )
    {
        printf("Ptr is Null.\n");
    }

    towork(ptr);                    // 引用传递,智能指针直接做为参数,可不用作为右值传递,
    if ( ptr == nullptr )
    {
        printf("===Ptr is Null.\n");
    }

    gowork(std::move(ptr));         // 值传递, 不能直接传递左值(unique_ptr不支持拷贝赋值),只能转换成右值传递
    if ( ptr == nullptr )
    {
        printf(">>>Ptr is Null.\n");
    }    
     return 0;    
}

程序运行情况:

 

标签:std,C++,num,printf,unique,ptr,指针
From: https://www.cnblogs.com/weijian168/p/17921963.html

相关文章

  • 【每周例题】蓝桥杯 C++ 区间最大和
    区间最大和题目蓝桥杯区间最大和题目分析  这道题涉及到了区间问题,我们首先要了解规定的该区间范围:1<p且p+k一1<n,我们将其转化:1<p<n-k+1,当我们得到这个区间的时候,需要求该区间的最大和可以用双重for循环搞定。代码 #include<iostream>usingnamespacestd;int......
  • Unity 捕获C++ dll的Crash
    转载:C#程序调用第三dll引起崩溃,但是try无法捕捉到第三方dll的异常-.net程序调试-少有人走的路(skcircle.com) 问题:一个第三方的dll,调用它的函数会引起程序崩溃,但是try却无法捕捉到此异常。 因为没有Try到异常,那么一个未处理的异常,会导致整个进程终止。这就是程序会崩溃的原......
  • static关键字在C/C++中的用法
    在C++中,static关键字有几种不同的用法:1.静态(局部)变量在函数内部声明的变量或类中声明的变量前加上static,表示这个变量的生命周期为整个程序运行期间,而不是仅在函数执行期间。静态变量在第一次调用时初始化,之后保持其值直到程序结束。voidfunc(){staticintcount......
  • C++基础 -11- 类的构造函数
     ———————类的构造函数——————— ......
  • C++ Qt开发:StandardItemModel数据模型组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍StandardItemModel数据模型组件的常用方法及灵活运用。QStandardItemModel是Qt中用于存储标准......
  • Qt/C++视频监控Onvif工具/组播搜索/显示监控画面/图片参数调节/OSD管理/祖传原创
    一、前言能够写出简单易用而又不失功能强大的组件,一直是我的追求,简单主要体现在易用性,不能搞一些繁琐的流程和一些极难使用的API接口,或者一些看不懂的很难以理解的函数名称,一定是要越简单越好。功能强大主要体现在功能的完整性,常规的接口肯定是必备的,然后在默认值方面,尽量将值设......
  • Visual Studio如何再次配置一个曾经配置过的C++库?
      本文介绍在VisualStudio软件中调用C++各种配置、编译完毕的第三方库的方法。  在撰写C++代码时,如果需要用到他人撰写的第三方库(例如地理数据处理库GDAL、矩阵运算库Armadillo等),并不能像Python等语言那样,安装好库后直接在不同代码文件中使用;而是需要每一次新建一个代码文......
  • 交个崔鹏题 OJ实践1-C /图的广度搜索/C++
    #include<iostream>#include<malloc.h>#include<queue>usingnamespacestd;#defineMAX10typedefintE;typedefstructNode{ intnextVex; structNode*next;}*node;structHeadNode{ Eelement; structNode*next;};typedefstruct......
  • C++标准库std::string的find_first_not_of 方法介绍:
    C++标准库std::string 的  find_first_not_of方法介绍: 例如:stra.find_first_not_of(s_fmt_a)在字符串stra中找到第一个不在s_fmt_a字符串中出现过的字符。stra="abc",abc字符都在s_fmt_a字符串里面出现过,所以第一个不在s_fmt_a里的字符是找不到的,返回......
  • C++ Qt开发:StringListModel字符串列表映射组件
    Qt是一个跨平台C++图形界面开发库,利用Qt可以快速开发跨平台窗体应用程序,在Qt中我们可以通过拖拽的方式将不同组件放到指定的位置,实现图形化开发极大的方便了开发效率,本章将重点介绍QStringListModel字符串映射组件的常用方法及灵活运用。QStringListModel是Qt中用于处理字符......