提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
提示:以下是本篇文章正文内容,下面案例可供参考
unique_ptr是独占指针,防止其他智能指针与其共享对象。
一、unique_ptr的用法
包含头文件
#include <memory>
1.初始化
与shared_ptr类似
两种初始化方式:1、传入指针通过构造函数初始化。2、也可以使用make_unique函数初始化。
int* p=new int(10);
unique_ptr<int> sp(p);
//unique_ptr<int> sp2(p);//error
//unique_ptr<int> sp2(sp);//error
auto sp3 = make_unique<int>(100);
2.常用操作
std::move()对象转移
#include <iostream>
#include <memory>
#include <mcheck.h>
using namespace std;
class foo
{
private:
int k_;
public:
foo(const int& k);
void foop();
~foo();
};
foo::foo(const int& k):k_(k){}
foo::~foo(){}
void foo::foop(){
cout<<"foo: "<<k_<<endl;
}
int main() {
setenv("MALLOC_TRACE", "m.log", 1);
mtrace();
auto sp = make_unique<foo>(10);
sp->foop();
auto sp2= move(sp);
sp2->foop();
//sp->foop();//Segmentation fault
return 0;
}
reset方法重新指定(释放对象)、通过release方法释放所有权()并返回原指针
int* k;
{
unique_ptr<int> sp4(make_unique<int>(10));
k = sp4.get();
sp4.release(); //释放所有权,对象还在,内存泄露
//sp4.reset();
}
cout << k << " " << *k << endl;
0x229a370 10
//0x229a370 0
二、unique_ptr的实现
解析见注释
代码如下(示例):
#include <mcheck.h> //内存泄露检测工具
#include <iostream>
using namespace std;
template <typename T>
class unique_ptr {
private:
T* ptr_;
//禁用拷贝构造函数和重载=,从而独占对象
unique_ptr(const unique_ptr& other);
unique_ptr operator=(const unique_ptr&);
void del() {
if (ptr_) //防止释放所有权后delete
{
delete ptr_;
ptr_ = nullptr; //防止野指针
}
}
public:
unique_ptr(T* ptr = nullptr);
~unique_ptr();
T& operator*() const {
return *ptr_;
}
void reset() {
del();
}
T* get() const {
return ptr_;
}
T* release() {
T* p = ptr_;
ptr_ = nullptr;
return p;
}
T* operator->() const {
return ptr_;
}
};
template <typename T>
unique_ptr<T>::unique_ptr(T* ptr) : ptr_(ptr) //模板类使用需指明类型
{}
template <typename T>
unique_ptr<T>::~unique_ptr() {
del();
}
template <typename T>
T* move(unique_ptr<T>& tmp) {
if (tmp.get()) {
return tmp.release();
}
}
// test
int main() {
setenv("MALLOC_TRACE", "m.log", 1);
mtrace();
unique_ptr<int> up(new int(10));
cout << " " << *up << endl;
int* p = up.release(); //释放unque_ptr的所有权,返回对象的地址
cout << "p: " << *p << endl;
delete p; //释放内存,否则内存泄露
struct num {
int a_;
int b_;
num(int a, int b) : a_(a), b_(b) {}
};
unique_ptr<num> up2(new num(1, 2));
cout << up2->a_ << endl;
unique_ptr<int> up3(new int[10]);
*(up3.get() + 3) = 10;
unique_ptr<int> up4(move(up3));
cout << "up4: " << *(up4.get() + 3) << endl;
return 0;
}