c++智能指针unique_ptr的使用

目录
  • 1.为什么需要unique_ptr
  • 2.什么是unique_ptr
  • 3.unique_ptr特性
  • 4.如何使用unique_ptr
    • 4.1简单使用
    • 4.2指向数组
  • 5.unique_ptr需要注意什么

1.为什么需要unique_ptr

与shared_ptr作用类似,需要解决内存泄漏的问题,但是却不需要使用shared_ptr的引用计数,所以为了减少消耗,就需要一个这样的智能指针。但是使用已被废弃的auto_ptr的话就会有新的问题,auto_ptr在使用过程中如果被拷贝构造或者赋值的话,被复制的auto_ptr就失去了作用,这个时候就需要在auto_ptr的基础上禁用拷贝构造以及赋值操作,也就成了unique_ptr。

2.什么是unique_ptr

一个unique_ptr独享它指向的对象。也就是说,同时只有一个unique_ptr指向同一个对象,当这个unique_ptr被销毁时,指向的对象也随即被销毁。使用unique_ptr需要引入<memory.h>

3.unique_ptr特性

unique_ptr禁用了拷贝构造以及赋值操作,也就导致了下面的这些操作无法完成。

void testFunction(std::unique_ptr<Test> t){
    t->getString();
}

void features(){
    // Disable copy from lvalue.
    //    unique_ptr(const unique_ptr&) = delete;
    //    unique_ptr& operator=(const unique_ptr&) = delete;
    //不能进行拷贝构造以及赋值运算,也就表示不能作为函数参数传递
     std::unique_ptr<Test> t(new Test);
     std::unique_ptr<Test> t2 = t; //编译报错
     std::unique_ptr<Test> t3(t);//编译报错
     testFunction(t);//编译报错
}

4.如何使用unique_ptr

4.1简单使用

void simpleUse(){
    Test *test = new Test;
    std::unique_ptr<Test> t(test);
     qDebug() << test  <<"获取原始指针"<< t.get() <<endl;

    //    t.release(); //释放其关联的原始指针的所有权,并返回原始指针,没有释放对象
    //    t.reset();// 释放对象
    t->getString();

    std::unique_ptr<Test> t2 = std::move(t); //交换使用权到t2;
    t2->getString();
}

4.2指向数组

和shared_ptr需要注意的地方一样,指向数组时要注意模板书写的方式,以及如何使用自定义删除器

错误写法:会导致内存泄露

void customRemover(){
    std::unique_ptr<Test> t(new Test[5]);
}

正确写法:

void customRemover(){
    std::unique_ptr<Test[]> t(new Test[5]);

    std::unique_ptr<Test, void(*)(Test *)> p2(new Test[5],[](Test *t){
        delete []t;
    });
}

5.unique_ptr需要注意什么

不要多个unique_ptr指向同一个对象
例如:

void repeatPointsTo(){
    Test *test = new Test;
    std::unique_ptr<Test> t(test);
    std::unique_ptr<Test> t2(test);
    //两个unique_ptrzhi'xi指向同一个对象,会导致这个对象被析构两次,导致问题出现
}

会导致对象会被多次析构,导致崩溃

到此这篇关于c++智能指针unique_ptr的使用的文章就介绍到这了,更多相关c++智能指针unique_ptr内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

时间: 2021-12-26

C++11智能指针unique_ptr用法使用场景分析

一.概述 C++ 标准模板库 STL(Standard Template Library) 一共给我们提供了四种智能指针:auto_ptr.unique_ptr.shared_ptr 和 weak_ptr,其中 auto_ptr 是 C++98 提出的,C++11 已将其摒弃,并提出了 unique_ptr 替代 auto_ptr.虽然 auto_ptr 已被摒弃,但在实际项目中仍可使用,但建议使用更加安全的 unique_ptr,后文会详细叙述.shared_ptr 和 weak_ptr 则是

C++11智能指针中的 unique_ptr实例详解

在前面一篇文章中,我们了解了 C++11 中引入的智能指针之一 shared_ptr 和 weak_ptr ,今天,我们来介绍一下另一种智能指针 unique_ptr . 往期文章参考: [C++11新特性] C++11 智能指针之shared_ptr [C++11新特性] C++11智能指针之weak_ptr unique_ptr介绍 unique是独特的.唯一的意思,故名思议,unique_ptr可以"独占"地拥有它所指向的对象,它提供一种严格意义上的所有权. 这一点和我们前面介绍

C++11新特性之智能指针(shared_ptr/unique_ptr/weak_ptr)

shared_ptr基本用法 shared_ptr采用引用计数的方式管理所指向的对象.当有一个新的shared_ptr指向同一个对象时(复制shared_ptr等),引用计数加1.当shared_ptr离开作用域时,引用计数减1.当引用计数为0时,释放所管理的内存. 这样做的好处在于解放了程序员手动释放内存的压力.之前,为了处理程序中的异常情况,往往需要将指针手动封装到类中,通过析构函数来释放动态分配的内存:现在这一过程就可以交给shared_ptr去做了. 一般我们使用make_shared来

C++11新特性中auto 和 decltype 区别和联系

C++11新特性中auto 和 decltype 区别和联系 一. auto简介 编程时候常常需要把表达式的值付给变量,需要在声明变量的时候清楚的知道变量是什么类型.然而做到这一点并非那么容易(特别是模板中),有时候根本做不到.为了解决这个问题,C++11新标准就引入了auto类型说明符,用它就能让编译器替我们去分析表达式所属的类型.和原来那些只对应某种特定的类型说明符(例如 int)不同.auto 让编译器通过初始值来进行类型推演.从而获得定义变量的类型,所以说 auto 定义的变量必须有初始

详解c++11新特性之模板的改进

C++11关于模板有一些细节的改进: 模板的右尖括号 模板的别名 函数模板的默认模板参数 模板的右尖括号 C++11之前是不允许两个右尖括号出现的,会被认为是右移操作符,所以需要中间加个空格进行分割,避免发生编译错误. int main() { std::vector<std::vector<int>> a; // error std::vector<std::vector<int> > b; // ok } 这个我之前都不知道,我开始学编程的时候就已经是C

浅析C++11新特性的Lambda表达式

lambda简介 熟悉Python的程序员应该对lambda不陌生.简单来说,lambda就是一个匿名的可调用代码块.在C++11新标准中,lambda具有如下格式: [capture list] (parameter list) -> return type { function body } 可以看到,他有四个组成部分: 1.capture list: 捕获列表 2.parameter list: 参数列表 3.return type: 返回类型 4.function body: 执行代码

C++智能指针shared_ptr分析

C++智能指针shared_ptr分析 概要: shared_ptr是c++智能指针中适用场景多,功能实现较多的智能指针.它采取引用计数的方法来实现释放指针所指向的资源.下面是我代码实现的基本功能. 实例代码: template<class T> class sharedptr { public: sharedptr(T* ptr) :_ptr(ptr) , _refCount(new int(1)) {} sharedptr(sharedptr<T>& sp) :_ptr

C++ 11新特性之大括号初始化详解

本文主要给大家介绍了关于C++11新特性之大括号初始化的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍: C++11之前,C++主要有以下几种初始化方式: //小括号初始化 string str("hello"); //等号初始化 string str="hello"; //大括号初始化 struct Studnet{ char* name; int age; }; Studnet s={"dablelv",18}; //

C++11新特性之自定义字面量

1.示例 C++11新标准中引入了用户自定义字面量,也叫自定义后缀操作符,即通过实现一个后缀操作符,将申明了该后缀标识的字面量转化为需要的类型.考察如下代码: long double operator"" _mm(long double x) { return x / 1000; } long double operator"" _m(long double x) { return x; } long double operator"" _km(

c++11新特性多线程操作实战

c++11多线程操作 线程 thread int main() { thread t1(Test1); t1.join(); thread t2(Test2); t2.join(); thread t3 = t1; thread t4(t1); thread t5 = std::move(t1); thread t6(std::move(t1)); return 0; } t3,t4创建失败,因为thread的拷贝构造和赋值运算符重载的原型是: thread(const thread&) = d

C++11新特性std::tuple的使用方法

1. 引入头文件 #include <tuple> 2. std::tuple初始化 std::tuple<int, std::string, float> t1(10, "Test", 3.14); 这里要注意,不是所有的C++ 11编译器都支持copy-list-initialization的方式.如下代码所示. std::tuple<int, int> foo_tuple() { return {1, -1}; // Error until N

C++11新特性std::make_tuple的使用

std::tuple是C++ 11中引入的一个非常有用的结构,以前我们要返回一个包含不同数据类型的返回值,一般都需要自定义一个结构体或者通过函数的参数来返回,现在std::tuple就可以帮我们搞定. 1.引用头文件 #include <tuple> 2. Tuple初始化 std::tuple的初始化可以通过构造函数实现. // Creating and Initializing a tuple std::tuple<int, double, std::string> resul