C++ | unique_ptr

unique_ptr

一个unique_ptr独占它所指向的对象。当unique_ptr被销毁时,它所指向的对象也被销毁。

初始化unique_ptr时只能使用直接初始化的方式,不能使用普通的拷贝赋值操作。

unique_ptr<string> p1;						//正确
unique_ptr<int> p2(new int(9));				//正确
unique_ptr<string> p3(new string("DAYH"));	//正确
unique_ptr<string> p4(p3);					//错误:unique_ptr不支持拷贝
unique_ptr<string> p5;						
p5 = p4;									//错误:unique_ptr不支持赋值

unique_ptr的一些操作。

unique_ptr<T> p

空只能指针,可以指向类型为T的对象,用delete释放对象资源

unique_ptr<T,D> p

空只能指针,可以指向类型为T的对象,用类型为D的可调用函数释放对象资源

unique_ptr<T,D> p(d)

空只能指针,可以指向类型为T的对象,用类型为D的对象d代替delete

p

if(p),若p指向一个对象,表达式为true

*p

解引用

p->attr

等价于(*p).attr

p->get()

返回p中保存的指针

swap(p,q)

交换p和q中的指针

p.swap(q)

交换p和q中的指针

p = nullptr

释放p指向的对象,将p置空

p.release()

p放弃对指针的控制权,返回指针,并将p置空

p.reset()

释放p指向的对象

p.reset(q)

提供内置指针q,将p指向这个对象,否则将p置空

p.reset(nullptr)

unique_ptr不能赋值和拷贝,但可以通过调用release()和reset()来转移对象控制权。

unique_ptr<int> p2(p1.release()); // release将p1置空,同时将对象所有权转移给p1
unique_ptr<int> p3(new int(9));
// 将所有权从p3转移给p2
p2.reset(p3.release()); // reset释放了p2原来的内存

release()返回unique_ptr当前保存的指针并将其置空。因此,p2被初始化为p1原来保存的指针,而p1被置空。

reset()令unique_ptr重新指向给定的指针。如果unique_ptr不为空,它原来的对象被释放。因此p2调用reset()释放了用p1初始化的对象,将p3的控制权转移给p2。

release()使用提示。

release()会切断unique_ptr和它原来管理的对象间的联系。release()返回的指针必须被记录,否则我们将失去它

p2.release();			// 错误:p2并未释放内存,只是放弃了该内存的控制权,导致我们失去了该指针
auto p = p2.release();	// 正确:但要记得delete p

删除器

向unique_ptr传递删除器。

智能指针在管理动态内存时使用delete来释放资源,当使用智能指针管理非动态内存(如 myclass a)时,我们需要定义删除器函数来代替delete完成对只能指针进行释放操作。

void fuc()
{
    myclass a;
    unique_ptr<myclass, decltype(end_fuc)*> p(&a, end_fuc);
}// fuc退出时,即使程序发生异常 shared_ptr也能通过调用end_fuc管理对象 

定义了删除器的智能指针,其在销毁时不会执行delete,而是调用删除器函数。

使用decltype来指明函数指针类型,decltype(end_fuc)返回一个函数类型,所以添加一个*来指明我们使用该类型的一个指针。

unique_ptrC++11 标准提供的智能指针,用于管理动态分配的对象。它使用了独占所有权的概念,保证了在不再需要指针时自动释放资源,从而避免了内存泄漏。 手撕 unique_ptr 的实现涉及到指针的拷贝和移动语义。下面是一个简单的手撕 unique_ptr 的示例代码: ```cpp template <typename T> class unique_ptr { public: explicit unique_ptr(T* ptr = nullptr) : ptr_(ptr) {} ~unique_ptr() { delete ptr_; } unique_ptr(const unique_ptr&) = delete; // 禁用拷贝构造函数 unique_ptr& operator=(const unique_ptr&) = delete; // 禁用拷贝赋值运算符 unique_ptr(unique_ptr&& other) noexcept : ptr_(other.ptr_) { other.ptr_ = nullptr; } unique_ptr& operator=(unique_ptr&& other) noexcept { if (this != &other) { delete ptr_; ptr_ = other.ptr_; other.ptr_ = nullptr; } return *this; } T& operator*() const { return *ptr_; } T* operator->() const { return ptr_; } T* get() const { return ptr_; } private: T* ptr_; }; ``` 上述代码中,我们定义了一个类模板 `unique_ptr`,它模拟了标准库中的 `std::unique_ptr` 功能。在构造函数中,我们接受一个指针作为参数,并将其保存在 `ptr_` 成员变量中。析构函数负责释放指针所指向的资源。为了遵循独占所有权的原则,我们禁用了拷贝构造函数和拷贝赋值运算符,而使用移动语义来实现赋值操作。`operator*` 和 `operator->` 用于重载解引用操作符,方便使用指针指向的对象。 需要注意的是,上述实现只是一个简单的手撕版 unique_ptr,并没有处理更复杂的边界情况和异常安全性。在实际使用中,建议使用标准库提供的 `std::unique_ptr`,它已经经过了充分测试和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

DAYH

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

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

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

打赏作者

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

抵扣说明:

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

余额充值