unique_ptr使用总结

头文件

#include 

初始化

用原始指针

std::unique_ptr pName {new std::string{“Hello”}};

使用make_unique

auto pName = std::make_unique(“Hello”);//c++14 support make_unique

可以用一个unique_ptr初始化另外一个unique_ptr吗?

不可以,但是可以进行所有权转移

vector可以装unique_ptr吗?

可以,但是unique_ptr不可拷贝,把已有的一个unique_ptr装进vector需要使用 std::move()

所有权转移的方式

方式一

auto up_name = std::make_unique(“Hello”);
std::unique_ptr up_new_name{up_name.release()};

方式二

auto up_name = std::make_unique(“Hello”);
std::unique_ptr up_new_name = std::move(up_name);

vector里边可以装unique_ptr

struct B {
  virtual void bar() { std::cout << "B::bar\n"; }
  virtual ~B() = default;
};
struct D : public B
{
    D() { std::cout << "D::D\n";  }
    ~D() { std::cout << "D::~D\n";  }
    void bar() override { std::cout << "D::bar\n";  }
};
std::unique_ptr p = std::make_unique();
std::vector> v;  // unique_ptr 能存储于容器
v.push_back(std::make_unique());
v.push_back(std::move(p));
v.emplace_back(new D);

unique_ptr可以指向一个数组

size_t len{10};
  std::unique_ptr pnums {new int[len]};
 for (size_t i {}; i

shared_ptr不具备这个功能,如果要支持,需要自己实现删除器

传参和返回unique_ptr

因为unique_ptr不能被copy,因此传参尽量使用引用类型

void func1(unique_ptr &up){
    cout<<*up<

返回unique_ptr

尽管不允许copy,但是作为返回值,返回一个即将销毁的局部变量是被允许的

unique_ptr func2(int a)
{
    unique_ptr up(new int(a));
    return up;
}

unique_ptr func1(int a)
{
    return unique_ptr (new int(a));
}

unique_ptr指向对象的析构时机

当智能指针析构时,unique_ptr对象所指向的对象也会被析构。调用reset()函数可以析构它所指向的对象,unique_ptr对象中的原生指针会被替换为空指针

auto pname = std::make_unique(“Hello”);
pname.reset()    // release memory for string obj

可以将新对象的地址传给reset()函数,这样旧对象就会被析构

pname.reset(new std::string{“World”});

直接给智能指针对象赋值为空指针也会调用析构函数

pname = nullptr;

检查unique_ptr是否为空

unique_ptr可以隐式地转换为布尔值。如果一个对象包含一个空指针,将会被转换为false 否则转换为true,因此可以用if来检查

auto up_name = std::make_unique(“Hello”);
if(up_name)
   std::cout<<“The name is ”<<*up_name<

unique_ptr自定义删除器

deleter是函数指针类型

是仿函数

或者std::function

void func(double *)
{
	cout<<"hello world"<
struct my_deleter
{
	operator ()(T * t)
	{
	   cout<<"hello ....."<  dn_ptr { new double {0.999}, func};
    
   // my_deleter myd;
  //  unique_ptr >  dn_ptr { new double {0.999}, myd};
   
    unique_ptr >  dn_ptr { new double {0.999}, func}; 
    cout<< *dn_ptr<

警告

智能指针都是 值语意,要么是栈上对象,或者是其他对象的直接数据成员,或者是标准库容器的元素,几乎不会出现下面的用法

shared_ptr  * = new shared_ptr(new Foo)

不要将其他的unique_ptr所指向的一个对象的地址值传给reset() 或者去生成一个新的unique_ptr对象,这种代码可能会通过编译,但是肯定会让程序崩溃

不能像对原生指针那样,对智能指针进行一些自减和自增操作

智能指针只能用来保存堆上分配的内存的地址

 int main(int argc, char** argv) {
    double dn = 0.999;
    unique_ptr dn_ptr { &dn};
    cout<< *dn_ptr<

保存了栈上对象,能取值,但是会crash,因为内存二次释放

你可能感兴趣的:(C-C++基础)