C++ 共享所有权(std :: shared_ptr)
示例
类模板std::shared_ptr定义了一个共享指针,该共享指针能够与其他共享指针共享对象的所有权。这与std::unique_ptr代表专有所有权相反。
共享行为是通过一种称为引用计数的技术来实现的,其中将指向对象的共享指针的数量存储在对象旁边。当此计数达到零时(通过销毁或重新分配最后一个std::shared_ptr实例),该对象将自动销毁。
// 创建:“ firstShared”是“ Foo”新实例的共享指针std::shared_ptr<Foo> firstShared = std::make_shared<Foo>(/*args*/);
要创建共享同一对象的多个智能指针,我们需要创建另一个shared_ptr别名作为第一个共享指针的别名。这有两种方法:
std::shared_ptr<Foo> secondShared(firstShared); // 第一种方式:复制构造std::shared_ptr<Foo> secondShared;
secondShared = firstShared; // 第二种方式:分配
上述任何一种方法,使secondShared一个共享指针,我们的情况下持有股票的Foo有firstShared。
智能指针就像原始指针一样工作。这意味着,您可以*用来取消引用它们。常规->运算符也可以正常工作:
secondShared->test(); // 调用Foo :: test()
最后,当最后一个别名shared_ptr超出范围时,将Foo调用我们实例的析构函数。
警告:当需要分配用于共享所有权语义的额外数据时,构造ashared_ptr可能会引发bad_alloc异常。如果向构造函数传递了常规指针,则它假定拥有所指向的对象,并在引发异常时调用删除程序。这意味着如果分配失败,将不会泄漏对象。但是,建议使用或,它们使实现能够优化内存分配。shared_ptr<T>(new T(args))Tshared_ptr<T>make_shared<T>(args)allocate_shared<T>(alloc, args)
使用shared_ptr分配数组([])
C ++ 11 C ++ 17不幸的是,没有直接的方法使用分配数组make_shared<>。
可以shared_ptr<>使用new和创建数组std::default_delete。
例如,要分配10个整数的数组,我们可以将代码编写为
shared_ptr<int> sh(new int[10], std::default_delete<int[]>());
std::default_delete在此处必须进行指定,以确保使用正确清除了分配的内存delete[]。
如果我们在编译时知道大小,则可以这样进行:
template<class Arr>struct shared_array_maker {};
template<class T, std::size_t N>
struct shared_array_maker<T[N]> {
std::shared_ptr<T> operator()const{
auto r = std::make_shared<std::array<T,N>>();
if (!r) return {};
return {r.data(), r};
}
};
template<class Arr>
auto make_shared_array()
-> decltype( shared_array_maker<Arr>{}() )
{ return shared_array_maker<Arr>{}(); }
然后make_shared_array<int[10]>返回一个shared_ptr<int>指向所有默认构造的10个整数的指针。
C ++ 17使用C ++ 17,shared_ptr获得了对数组类型的特殊支持。不再需要显式指定数组派发器,并且可以使用[]数组索引运算符取消引用共享指针:
std::shared_ptr<int[]> sh(new int[10]);sh[0] = 42;
共享的指针可以指向它拥有的对象的子对象:
struct Foo { int x; };std::shared_ptr<Foo> p1 = std::make_shared<Foo>();
std::shared_ptr<int> p2(p1, &p1->x);
这两个p2和p1自己的类型的对象Foo,但p2指向它的int成员x。这意味着,如果p1超出范围或被重新分配,则基础Foo对象仍将保持活动状态,确保p2不会悬空。
重要提示: Ashared_ptr仅了解自身以及shared_ptr使用别名构造函数创建的所有其他信息。它不知道任何其他指针,包括shared_ptr通过引用同一Foo实例创建的所有其他指针:
Foo *foo = new Foo;std::shared_ptr<Foo> shared1(foo);
std::shared_ptr<Foo> shared2(foo); // 不要这样做
shared1.reset(); // 这将删除foo,因为shared1
// 是拥有它的唯一shared_ptr
shared2->test(); // 不确定的行为:shared2的foo被
// 已删除!
shared_ptr的所有权转移
默认情况下,shared_ptr增加引用计数并且不转移所有权。但是,可以使用std::move以下方式转移所有权:
shared_ptr<int> up = make_shared<int>();// 转让所有权
shared_ptr<int> up2 = move(up);
// 此时,参考计数up = 0,并且
// 指针的所有权仅与引用计数= 1的up2一起
以上是 C++ 共享所有权(std :: shared_ptr) 的全部内容, 来源链接: utcz.com/z/326212.html