簡體   English   中英

C++ class 的幾個實例(但不是全部)共享一個向量

[英]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的作用! 正是這個引用計數

然而,訪問邏輯通常更容易; 例如,

我有一個向量Cstd::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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM