[英]C++ several instances (but not all) of a class sharing a vector
我想要一個 class C
,這樣C
的實例將std::vector<int>
作為私有成員。 現在C
的許多實例(但不是全部)將共享該向量並且為每個實例保留一個副本是我想要避免的。
例如,如果這個向量是單個 integer,我可以為 C 創建一個模板C
並像這樣:
template <int N>
class C {
// something
};
如果我希望所有實例共享該向量而不是某些實例,那么我會將變量 static 聲明為
class C {
static std::vector<int> _vec;
我正在尋找的是中間的東西。 例如,我可以將shared_ptr
保留為私有非靜態成員,如
class C {
std::shared_ptr<std::vector<int>> _vec;
}
這將照顧到 object 的生命周期,有一些維護共享所有權的開銷以及每個實例的額外指針。 我可以保留一個引用,讓實例的創建者負責生命周期,但避免shared_ptr
的開銷。 這個設計問題有更好的方法嗎?
...這樣 C 的實例將 std::vector 作為私有成員持有。 現在 C 的許多實例(但不是全部)將共享該向量
所以,這是自相矛盾的。 您無法持有一個實例並安全地共享該實例。
這是指針的經典用例; 更具體地說,共享指針的經典用例,正如您已經注意到的那樣。
我可以保留一個引用,讓實例的創建者來處理生命周期,
/me 發出銷毀后訪問警報
你很快就會發現那是行不通的。 生命周期並不像你想象的那樣,而是在擁有對象的生命周期結束時結束。 所以,這打破了。 (另外,你會發現在幕后,分發引用編譯成與分發原始指針相同的代碼——它只是更安全,並且在語言中自動取消引用;你實際上並沒有在那里保存 memory 間接尋址。包含引用的類仍然需要知道它們正在處理的 object 的地址,這與擁有一個指針是一樣的,如果你詢問你的 CPU。)
它會中斷,除非分發引用的東西對它分發的引用數量進行計數,減去它分發的屬於被解構的C
實例的引用,然后在該數字達到 0 時立即解構向量。大膽猜測shared_ptr
的作用! 正是這個引用計數。
然而,訪問邏輯通常更容易; 例如,
我有一個向量
C
,std::vector<C> lexicon
,並且所有持有C._vec
需要在完整的lexicon
從 scope 中刪除時准確刪除,所以我手動處理
實際上不需要引用計數,因此開銷較低。 你確實可以通過分發引用來解決這個問題——但在那種情況下我實際上更願意分發原始指針:它們同樣不暗示所有權,你不會不小心復制了std::vector<int>
當你按值傳遞指針時。
如果您的生命周期跟蹤不如該示例那么簡單:
參考文獻中沒有神奇的使用跟蹤; 你需要一些東西來跟蹤是否有東西仍然持有你的個人vector
的句柄。 該跟蹤正是shared_ptr
產生的“開銷”。 沒有辦法解決它。
因此,私有shared_ptr
是正確的方法:
class C {
private:
std::shared_ptr<std::vector<int>> _vec;
}
您的static
方法在這里無處可去-只有當所有實例共享同一個向量時才有意義,該向量基本上應該從時間開始一直存在到結束,即使那樣,它也是一個可以導致的解決方案以 static 初始化順序慘敗的形式出現額外的麻煩。 我建議幾乎在所有情況下都不要這樣做。
(另外,一個static
成員也歸結為查找相同地址的代碼——因此,在性能方面,與指針相同。同樣,這里沒有真正獲勝。)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.