#######################智能指针(智能指针是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保在离开指针所在作用域时,自动正确的销毁动态分配的对象,防止内存泄漏)
头文件#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