智能指针-unique_ptr的用法和实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


提示:以下是本篇文章正文内容,下面案例可供参考

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;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Attention is all you

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值