美文网首页
c++智能指针(unique_ptr)

c++智能指针(unique_ptr)

作者: arkliu | 来源:发表于2022-11-13 07:02 被阅读0次

在c++11中通过引入只能指针的概念,使得c++程序猿不需要手动释放内存

智能指针的分类

  • std::unique_ptr
  • std::shared_prt
  • std::weak_ptr
    注意:
    std::auto_ptr已被废弃

unique_ptr

  • unique_ptr 在任何给定的时刻,只能由一个指针管理内存
  • 当指针超出作用域时,内存将自动释放
  • 该类型指针不可copy,只能move

unique_ptr的三种创建方式

  • 通过已有裸指针创建

  • 通过new创建

  • 通过std::make_unique创建(推荐)

  • unique_ptr可以通过get()获取地址

  • unique_ptr实现了->与*
    即可以通过->调用成员函数
    可以通过* 调用解引用

unique_ptr创建

cat.h

#ifndef CAT_H
#define CAT_H
#include<string>
#include<iostream>
using namespace std;
class Cat {
    public:
        Cat(string name);
        Cat() = default;
        ~Cat();

        void cat_info()const{
            cout << "cat ino name:"<<name << endl;
        }

        string get_name() const {
            return name;
        }

        void set_name(const string &name) {
            this->name = name;
        }

    private:
        string name{"mimi"};
};    
#endif

cat.cpp

#include "cat.h"

Cat::Cat(string name) :name(name) {
     cout << "constructor of cat  " << name<< endl;
}

Cat::~Cat() {
    cout << "Deconstructor of cat  " << name << endl;
}
#include <iostream>
#include <memory>
#include "cat.h"
using namespace std;

int main() {
    // 栈上分配
    Cat c1("ok");
    c1.cat_info();

    // 堆上分配,裸指针
    Cat * c_cp1 = new Cat("yy");
    c_cp1->cat_info();
    delete c_cp1;

    //------第一种  用已经存在的地址初始化智能指针  不推荐-----
    Cat * c_p2 = new Cat("tts");
    unique_ptr<Cat> uc_p2(c_p2);
    uc_p2->cat_info();

    //------第二种-----
    unique_ptr<Cat>uc_p3{new Cat("dd")};
    uc_p3->cat_info();
    uc_p3->set_name("oo");
    uc_p3->cat_info();

    //------第三种 c++14标准 推荐使用-----
    unique_ptr<Cat>uc_p4 = make_unique<Cat>();
    uc_p4->cat_info();
    uc_p4->set_name("oo");
    uc_p4->cat_info();
    return 0;
}

get()方法返回裸指针

#include<iostream>
#include<string>
#include<memory>
using namespace std;

class Test {

};

int main() {
    Test* test = new Test(); // 定义原始指针test,并分配内存
    unique_ptr<Test>test_ptr(test);  // 创建智能指针test_ptr,用于管理原始指针test
    cout << "         裸指针的值:" << test << endl;
    cout << "test_ptr.get()的值:" << test_ptr.get() << endl;
    cout << "    test_ptr的地址:" << &test_ptr << endl;
    return 0;
}
image.png

函数调用与unique_ptr

  • 值传递
    需要用std::move来转移内存的拥有权
    如果参数直接传入std::make_unique语句,自动转换为move
void do_with_cat_pass_value(unique_ptr<Cat> c) {
    c->cat_info();
}


unique_ptr<Cat>uc_p1 = make_unique<Cat>("hello..");
do_with_cat_pass_value(std::move(uc_p1));
do_with_cat_pass_value(make_unique<Cat>("world.."));
  • 引用传递
    如果设置参数为const则不能改变指向
    比方说reset()
  • reset()方法为智能指针清空方法
void do_with_cat_pass_ref(unique_ptr<Cat> &c) {
    c->set_name("hhhhhhh");
    c->cat_info();
    c.reset();
}

unique_ptr<Cat>uc_p2 = make_unique<Cat>("hello..");
do_with_cat_pass_ref(uc_p2);
cout << "uc_p2 address is :"<<uc_p2.get()<<endl;
image.png
  • 值返回
    指向一个local object
    可以用做链式函数
unique_ptr<Cat> get_unique_ptr() {
    unique_ptr<Cat> p_cat = make_unique<Cat>("nmnm");
    return p_cat;
}

get_unique_ptr()->cat_info();

\color{red}{不支持指针的运算(+, -, ++, --)}

用nullptr赋值给unique_ptr将释放对象

#include <iostream>
#include <memory>
#include<string>
using namespace std;

class Cat {
    public:
        Cat(string name);
        Cat() = default;
        ~Cat();

        void cat_info()const{
            cout << "cat ino name:" << name << endl;
        }

        string get_name() const {
            return name;
        }

        void set_name(const string &name) {
            this->name = name;
        }

    private:
        string name{"mimi"};
};  

Cat::Cat(string name) :name(name) {
     cout << "constructor of cat  " << name<< endl;
}

Cat::~Cat() {
    cout << "Deconstructor of cat  " << name << endl;
}

int main() {
    unique_ptr<Cat> pu(new Cat("tony"));
    cout <<"赋值前:"<<endl;
    if (pu != nullptr)
    {
        cout <<"pu 不是空的"<<endl;
    }
    pu = nullptr;
    if (pu == nullptr)
    {
        cout <<"pu 是空的"<<endl;
    }
    
    return 0;
}
image.png

release释放对原始指针的控制权

release释放对原始指针的控制权,将unique_ptr置为空,返回裸指针

// 函数fun1需要使用指针,但是不对这个指针负责
void fun1(const Cat* cat_ptr) {
    cout << cat_ptr->get_name() << endl;
}

// 函数fun2需要使用指针,并且会对这个指针负责
void fun2(const Cat* cat_ptr) {
    cout << cat_ptr->get_name() << endl;
    delete cat_ptr;
}

// 函数fun3需要使用指针,但是不对这个指针负责
void fun3(const unique_ptr<Cat> &cat_ptr) {
    cout << cat_ptr->get_name() << endl;
}

// 函数fun4需要使用指针,并且会对这个指针负责
void fun4(const unique_ptr<Cat> cat_ptr) {
    cout << cat_ptr->get_name() << endl;
}

int main() {
    unique_ptr<Cat> pu(new Cat("tony"));
    // fun1(pu.get());
    // fun2(pu.release());

    fun4(std::move(pu));
    if (pu == nullptr)
    {
        cout <<"pu 是空指针"<<endl;
    }
    return 0;
}

reset()释放对象

pp.reset()  //释放pp对象指向的资源对象
pp.reset(nullptr)  //释放pp对象指向的资源对象
pp.reset(new Cat("jerry"))  //释放pp对象指向的资源对象,同时指向新对象

swap() 交换两个unique_ptr的控制权

void swap(unique_ptr<T> &right);

unique_ptr不是绝对安全

unique_ptr不是绝对安全,如果程序调用exit()退出, 全局的unique_ptr可以自动释放,但是局部的unique_ptr无法释放。

unique_ptr<Cat> pu(new Cat("全局的猫"));

int main() {
    unique_ptr<Cat> pu(new Cat("局部的猫"));
    return 0;
    //exit(0);
}

此时程序结束,全局的和局部的都被释放了


image.png

将上面的退出方式,改为exit,局部的对象就不会被释放


image.png

unique_ptr支持数组

int main() {
    // unique_ptr<Cat[]> pu(new Cat[2]);
    unique_ptr<Cat[]> pu(new Cat[2] {string("狸猫"), string("家猫")});
    cout << pu[0].get_name() << "===" << pu[1].get_name()<< endl;
    return 0;
}
image.png

相关文章

  • c++11 智能指针

    智能指针介绍 C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, wea...

  • 智能指针

    C++ 11 智能指针 unique_ptr、shared_ptr 与 weak_ptr C++ 11 中有 un...

  • c++ 11智能指针

    1 概要 C++ 11 包含了智能指针,需要包含头文件#include unique_ptr

  • 智能指针

    C++里面的智能指针包括auto_ptr, shared_ptr, unique_ptr, weak_ptr四种。...

  • C++11智能指针

    C++里面的四个智能指针: auto_ptr, unique_ptr,shared_ptr, weak_ptr 其...

  • 智能指针

    关键点## RAII机制 C++操作符重载 参考链接## C++11智能指针之unique_ptr shared_...

  • c++11智能指针(二) unique_ptr

    unique_ptr是一个独占指针,它不允许其他的智能指针共享其内部的指针。例如 初始化unique_ptr 指定...

  • 现代 C++:一文读懂智能指针

    智能指针 C++11 引入了 3 个智能指针类型: std::unique_ptr :独占资源所有权的指针。...

  • C++11智能指针

    智能指针 unique_ptr shared_ptr weak_ptr 在C98中,智能指针通过一个模...

  • modern c++(5)-智能指针

    auto_ptr与unique_ptr auto_ptr与unique_ptr都是独占所有权的智能指针类型,前者由...

网友评论

      本文标题:c++智能指针(unique_ptr)

      本文链接:https://www.haomeiwen.com/subject/pjzlzrtx.html