std::shared_ptr
首先来介绍shared_ptr,包含在memory头文件中,它的存在,使得更容易也更安全地使用动态内存。
智能指针也是模板,常用其初始化方式有以下几种。初始化方式:
1)默认初始化方式。
std::shared_ptr p1; // 指向空string
std::shared_ptr> p2; // 指向int的list
2)使用make_shared函数模板,make_shared声明如下:(推荐)
template
shared_ptr make_shared (Args&&... args);
从声明可以看出其用法,必须指定想要创建的对象的类型,例如:
// 指向一个值为3的int的shared_ptr
std::shared_ptr p3 = std::make_shared(3);
// 指向值为"9999"的string
std::shared_ptr p4 = std::make_shared(4, '9');
// 更简洁的方式,使用auto保存返回结果,构造一个指向空vector
auto p5 = std::make_shared>();
表示使用括号内参数来构造给定的类型对象。
3) 结合new,直接初始化形式
std::shared_ptr p2(new int(4)); // 必须显示初始化,不支持隐式转换。
shared_ptr会根据其所指向的对象的引用计数是否为0来决定是否销毁该对象,,并释放所占用的内存。注意不要混合使用普通指针和智能指针,若将一个智能指针绑定到一个普通指针时,我们就把内存的责任交给share_ptr来处理,就不要再使用普通指针来访问内存了。
4) reset方式
std::shared_ptr sp2;
sp2.reset(new int(3));
std::weak_ptr
std::weak是对对象的弱引用,是一种不控制对象生存期的指针,只是用于访问对象,通俗地说就是当没有shared_ptr之类指针指向对象时,即使有weak_ptr指向对象,对象依然会被释放。
初始化代码示例:
#include
#include
int main ()
{
// 构建一个shared_ptr
auto sp = std::make_shared(42);
std::cout << "sp use count is " << sp.use_count() << std::endl;
// 方式1 通过构造函数初始化
std::weak_ptr wp1(sp);
std::cout << "sp use count is " << sp.use_count() << std::endl;
// 方式2 通过拷贝构造函数来初始化
std::weak_ptr wp2(wp1);
std::cout << "sp use count is " << sp.use_count() << std::endl;
// 方式3 通过weak_ptr来赋值初始化
std::weak_ptr wp3;
wp2 = wp1;
std::cout << "sp use count is " << sp.use_count() << std::endl;
// std::weak_ptr 访问对象的方式举例
if (!wp2.expired())
{
if (auto np2 = wp2.lock())
{
std::cout << "-----np2 point to value is " << *np2 << std::endl;
}
}
sp.reset();
if (wp2.expired())
{
std::cout << "obj has been dectruct." << std::endl;
}
else
{
if (auto np2 = wp2.lock())
{
std::cout << "====np2 point to value is " << *np2 << std::endl;
}
}
return 0;
}
输出信息如下:
sp use count is 1
sp use count is 1
sp use count is 1
sp use count is 1
-----np2 point to value is 42
obj has been dectruct.
std::weak_ptr因为不管理对象的生命周期,所以它一般适用于那些资源对象,能用就用,如果已经销毁了就不用的使用场景。
std::unique_ptr指针
一个unique_ptr “拥有”它所指向的对象,任意时刻只能有一个unique_ptr指针指向一个给定的对象。unique_ptr的初始化方式如下:
#include
#include
int main ()
{
// 方式1 使用默认构造函数
std::unique_ptr up1;
// 方式2 通过内置指针构造
std::unique_ptr up3(new double(9.9));
std::cout << "up3 point to value: " << *up3 << std::endl;
// 方式3 使用reset
std::unique_ptr up4;
up4.reset(new double(8.8));
std::cout << "up4 point to value: " << *up4 << std::endl;
// 方式4 使用make_unique c++14才支持
std::unique_ptr up5 = std::make_unique(7.7);
std::cout << "up5 point to value: " << *up5 << std::endl;
return 0;
}
release结合reset的unique_ptr的用法
#include
#include
int main ()
{
std::unique_ptr up1(new int(1));
std::cout << "up1 point to value: " << *up1 << std::endl;
// release 放弃对指针的控制权,返回指针并将up1置空
std::unique_ptr up2(up1.release());
std::cout << "up2 point to value: " << *up2 << std::endl;
std::unique_ptr up3(new int(3));
// 将所有权从up2转移到up3
up3.reset(up2.release());
std::cout << "up3 point to value: " << *up3 << std::endl;
std::unique_ptr up4 = std::make_unique(4);
//up4.release(); // 错误写法:up4不会释放内存,且丢失了其之前所指向对象的指针
std::cout << "up4 point to value: " << *up4 << std::endl;
auto p = up4.release(); // 正确写法:需要记录返回的指针且记得delete p 操作
delete p;
std::cout << "hello world" << std::endl;
return 0;
}
输出信息如下:
up1 point to value: 1
up2 point to value: 1
up3 point to value: 1
up4 point to value: 4
hello world
std::unique_ptr移动构造
#include
#include
// std::unique_ptr 不支持copy 构造和 copy赋值
int main ()
{
std::unique_ptr up1 = std::make_unique(1);
std::unique_ptr up2(std::move(up1));
std::unique_ptr up3;
up3 = std::move(up2);
std::cout << "up3 point to value: " << *up3 << std::endl;
return 0;
}
好了,以上都是比较基本的用法,暂且写这么多。