std::allocate_shared, std::allocate_shared_for_overwrite
| 定義於標頭檔案 <memory> |
||
| template< class T, class Alloc, class... Args > shared_ptr<T> allocate_shared( const Alloc& alloc, Args&&... args ); |
(1) | (C++11 起) |
| template< class T, class Alloc > shared_ptr<T> allocate_shared( const Alloc& alloc, std::size_t N ); |
(2) | (C++20 起) |
| template< class T, class Alloc > shared_ptr<T> allocate_shared( const Alloc& alloc ); |
(3) | (C++20 起) |
| template< class T, class Alloc > shared_ptr<T> allocate_shared( const Alloc& alloc, std::size_t N, |
(4) | (C++20 起) |
| template< class T, class Alloc > shared_ptr<T> allocate_shared( const Alloc& alloc, |
(5) | (C++20 起) |
template< class T, class Alloc > shared_ptr<T> allocate_shared_for_overwrite( const Alloc& alloc ); |
(6) | (C++20 起) |
| template< class T, class Alloc > shared_ptr<T> allocate_shared_for_overwrite( const Alloc& alloc, |
(7) | (C++20 起) |
使用 alloc 的副本(為未指定的 value_type 重繫結)分配一個物件的記憶體,並用提供的引數初始化該物件。返回一個管理新建立物件的 std::shared_ptr 物件。
T,其構造方式如同 std::allocator_traits<Alloc>::construct(a, pt, (std::forward<Args>(args)...),其中 pt 是一個 std::remove_cv_t<T>* 指標,指向足以容納 std::remove_cv_t<T> 型別物件的儲存。如果要銷燬該物件,則其銷燬方式如同 std::allocator_traits<Alloc>::destroy(a, pt),其中 pt 是指向該 std::remove_cv_t<T> 型別物件的指標。
Alloc,它是 alloc 的一個可能被重繫結的副本。|
此過載僅若 |
(C++20 起) |
T 是無界陣列型別才參與過載決議。T。每個元素都有一個預設初始值。T 是有界陣列型別才參與過載決議。T 是無界陣列型別才參與過載決議。T。每個元素的初始值為 u。T 是有界陣列型別才參與過載決議。T。- 若
T不是陣列型別,則該物件的構造方式如同 ::new (pv) T,其中 pv 是一個 void* 指標,指向足以容納T型別物件的儲存。如果要銷燬該物件,則其銷燬方式如同 pt->~T(),其中 pt 是指向該T型別物件的指標。 - 若
T是有界陣列型別,則每個元素的初始值是未指定的。
T 不是陣列型別或是有界陣列型別才參與過載決議。T 是無界陣列型別才參與過載決議。
陣列元素的初始化與銷燬在下文描述中,a 的型別為
2,3) std::allocator_traits<Alloc>::construct(a, pu)
4,5) std::allocator_traits<Alloc>::construct(a, pu, u)
6,7) ::new (pv) U
當返回的 std::shared_ptr 所管理的物件生命週期結束時,或當陣列元素的初始化丟擲異常時,已初始化的元素將按照其原始構造順序的逆序被銷燬。 對於要銷燬的每個非陣列型別 6,7) pu->~U(),其中 pu 是指向該
U 型別陣列元素的指標 |
(C++20 起) |
[編輯] 引數
| alloc | - | 要使用的分配器 (Allocator) |
| args... | - | 用於構造 T 例項的引數列表 |
| N | - | 要使用的陣列大小 |
| u | - | 用於初始化陣列中每個元素的初始值 |
[編輯] 返回值
指向 T 型別物件的 std::shared_ptr,若 T 為無界陣列型別,則為 std::remove_extent_t<T>[N](C++20 起)。
對於返回的 std::shared_ptr r,r.get() 返回一個非空指標,且 r.use_count() 返回 1。
[編輯] 異常
可能丟擲 Alloc::allocate() 或 T 的建構函式所丟擲的異常。如果丟擲異常,(1) 沒有效果。如果在陣列構造過程中丟擲異常,已經初始化的元素將按逆序銷燬(C++20 起)。
[編輯] 注意
這些函式通常會分配比 sizeof(T
) 更多的記憶體,以便為內部記賬結構(如引用計數)留出空間。
與 std::make_shared 類似,此函式通常只執行一次分配,並將 T 物件和控制塊都放在分配的記憶體塊中(標準推薦但不強制要求這樣做,所有已知的實現都這樣做)。alloc 的一個副本作為控制塊的一部分儲存,以便在共享和弱引用計數都達到零時用於釋放記憶體。
與 std::shared_ptr 的建構函式不同,std::allocate_shared 不接受一個獨立的自定義刪除器:提供的分配器用於銷燬控制塊和 T 物件,以及釋放它們共享的記憶體塊。
|
std::shared_ptr 支援陣列型別(自 C++17 起),但 |
(C++20 前) |
一個建構函式使用型別為 U* 的指標 ptr “啟用 shared_from_this” 是指,它確定 U 是否有一個無歧義且可訪問的(C++17 起)基類,該基類是 std::enable_shared_from_this 的特化,如果是,則建構函式求值 if (ptr != nullptr && ptr->weak_this .expired())
ptr->weak_this = std::shared_ptr<std::remove_cv_t<U>>
(*this, const_cast<std::remove_cv_t<U>*>(ptr)); 。
對 weak_this 的賦值不是原子的,並與對同一物件的任何潛在併發訪問衝突。這確保了將來對 shared_from_this() 的呼叫將與此原始指標建構函式建立的 std::shared_ptr 共享所有權。
上述程式碼中的測試 ptr->weak_this .expired() 確保如果 weak_this 已經指示了一個所有者,則不會重新賦值。此測試自 C++17 起是必需的。
| 特性測試宏 | 值 | 標準 | 特性 |
|---|---|---|---|
__cpp_lib_smart_ptr_for_overwrite |
202002L |
(C++20) | 使用預設初始化建立智慧指標(std::allocate_shared_for_overwrite,std::make_shared_for_overwrite,std::make_unique_for_overwrite);過載 (6,7) |
[編輯] 示例
#include <cstddef> #include <iostream> #include <memory> #include <memory_resource> #include <vector> class Value { int i; public: Value(int i) : i(i) { std::cout << "Value(), i = " << i << '\n'; } ~Value() { std::cout << "~Value(), i = " << i << '\n'; } void print() const { std::cout << "i = " << i << '\n'; } }; int main() { // Create a polymorphic allocator using the monotonic buffer resource std::byte buffer[sizeof(Value) * 8]; std::pmr::monotonic_buffer_resource resource(buffer, sizeof(buffer)); std::pmr::polymorphic_allocator<Value> allocator(&resource); std::vector<std::shared_ptr<Value>> v; for (int i{}; i != 4; ++i) // Use std::allocate_shared with the custom allocator v.emplace_back(std::allocate_shared<Value>(allocator, i)); for (const auto& sp : v) sp->print(); } //< All shared pointers will automatically clean up when they go out of scope.
輸出
Value(), i = 0 Value(), i = 1 Value(), i = 2 Value(), i = 3 i = 0 i = 1 i = 2 i = 3 ~Value(), i = 0 ~Value(), i = 1 ~Value(), i = 2 ~Value(), i = 3
[編輯] 缺陷報告
下列更改行為的缺陷報告追溯地應用於以前出版的 C++ 標準。
| 缺陷報告 | 應用於 | 釋出時的行為 | 正確的行為 |
|---|---|---|---|
| LWG 3216 | C++20 | std::allocate_shared 在構造和銷燬物件前總是重繫結分配器 |
重繫結是可選的 |
| LWG 4024 | C++20 | 不清楚在 std::allocate_shared_for_overwrite 中構造的物件如何被銷燬 |
已明確 |
[編輯] 參閱
構造新的 shared_ptr(公開成員函式) | |
| (C++20 起) |
建立一個管理新物件的共享指標 (函式模板) |