一千萬個為什麽

搜索

C ++智能指針:共享指針與共享數據

在此富有洞察力的文章,其中一位Qt程序員試圖解釋Qt實現的各種智能指針。在開始時,他區分共享數據和共享指針本身:

首先,讓我們直截了當:   分享之間有區別   指針和共享數據。當你   分享指針,價值   指針及其生命周期受到保護   通過智能指針類。其他   單詞,指針是不變的。   但是,指針的對象   指的是完全在外面   它的控制。我們不知道是不是   物體是否可以復制,如果是的話   可分配與否。

     

現在,數據共享涉及到   智能指針類知道什麽   關於共享的數據。事實上,   重點是數據是   被分享,我們不關心如何。   指針正在被使用的事實   分享數據是無關緊要的   這點。例如,你沒有   真的關心Qt工具類是怎樣的   含蓄地分享,是嗎?什麽   對你而言,重要的是他們是共享的   (從而減少內存消耗)和   他們的工作好像不是。

坦率地說,我只是不解釋這個解釋。文章評論中有一個澄清請求,但我沒有發現作者的解釋充分。

如果您了解這一點,請解釋。這種區別是什麽,以及其他共享指針類(即來自boost或新的C ++標準)如何適應這種分類?

提前致謝

最佳答案

在稍後的評論中,他稍微澄清了這個問題

這是我在第一部分嘗試解決的重點。當您使用QSharedPointer時,您將共享指針的所有權。該類僅控制和處理指針 - 其他任何內容(如訪問數據)都在其範圍之外。使用QSharedDataPointer時,您正在共享數據。該類用於隱式共享:因此它可能會分開。

試圖解釋:

重要的是,“指針”並不意味著在這種情況下存儲地址的對象,但它意味著對象所在的存儲位置(地址本身)。嚴格來說,我想,你必須說你在分享這個地址。因此, boost :: shared_ptr 是一個共享“指針”的智能指針。 boost :: intrusive_ptr 或其他侵入式智能指針似乎也共享指針,雖然知道指向的對象(它有一個引用計數成員或函數遞增/遞減它)。

示例:如果有人與您共享一個黑盒子並且他不知道黑盒子裏有什麽,它類似於共享指針(代表盒子),而不是數據(盒子裏面的內容)。事實上,你甚至不知道盒子裏面的東西是可共享的(如果盒子裏什麽都沒有的話怎麽辦?)。智能指針由您和另一個人代表(當然,您不會共享),但地址是框,是共享的。

共享數據意味著智能指針足夠了解指向的數據,它可能會改變指向的地址(這需要復制數據等)。所以,現在指針可能指向不同的地址。由於地址不同,地址不再共享。這也是 std :: string 在某些實現上所做的事情:

std::string a("foo"), b(a);
//a and b may point to the same storage by now.
std::cout << (void*)a.c_str(), (void*)b.c_str();
//but now, since you could modify data, they will
//be different
std::cout << (void*)&a[0], (void*)&b[0];

Sharing data does not necessarily mean you have a pointer presented to you. You may use a std::string by pure means of a[0] and cout << a; and never touch any of the c_str() functions. Still sharing may go on behind the scene. The same thing happens with many Qt classes and classes of other widget toolkits too, which is called implicit sharing (or copy on write). So i think one may sum it up like this:

  • 共享指針:當我們復制智能指針時,我們總是指向相同的地址,這意味著我們共享指針值。
  • 分享數據:我們可能會在不同時間指向不同的地址。暗示我們知道如何將數據從一個地址復制到另一個地址。

所以試圖分類

  • boost::shared_ptr, boost::intrusive_ptr: Share the pointer, not the data.
  • QString, QPen, QSharedDataPointer: Share the data it contains.
  • std::unique_ptr, std::auto_ptr (and also QScopedPointer): Neither share the pointer, nor the data.

轉載註明原文: C ++智能指針:共享指針與共享數據