2013-05-07 102 views
5
typedef boost::shared_ptr<SomeData> data_ptr; 
data_ptr cached_ptr; // class member 
bool someWork(data_ptr& passed_ptr) 
{ 
    // must copy passed_ptr = cached_ptr under some conditions 
    // without pointing at the same memory 
    // I saw somewhere that I should do 
    // passed_ptr.reset(new SomeData(???)) 
    // I don't have a "reset" on passed_ptr 
} 

我看了文檔;複製boost :: shared_ptr

拷貝和轉換構造

shared_ptr(shared_ptr const & r); // never throws 
template<class Y> shared_ptr(shared_ptr<Y> const & r); // never throws 
Requires: Y* should be convertible to T*. 

Effects: If r is empty, constructs an empty shared_ptr; otherwise, 
     constructs a shared_ptr that shares ownership with r. 

我不知道如何工作的 - 是這樣嗎?

passed_ptr = shared_ptr(cached_ptr); 

? const會去哪裏?這是什麼意思,他們分享所有權?那麼它不是副本,如果我修改「passed_ptr」,更改會影響「cached_ptr」?

我找不到示例...請幫助。

謝謝。

回答

10

好吧,如果你有一個shared_ptr,你把它分配給另一個shared_ptr,這兩個共享指針將共享對象的所有權 - 意爲尖銳的物體的所有權引用計數將增加一個。

事實上,在上面的線,你不需要建立一個臨時共享指針都沒有。這是不夠的:

passed_ptr = cached_ptr; 

無論如何,複製構造shared_ptr基本上遵循同樣的邏輯:你以一個共享指針,你最終與共同擁有同一個物體的兩個共享指針(這意味着只有當這兩個共享指針的被破壞時,對象纔會被銷燬)。所以,當你這樣做:

passed_ptr = shared_ptr(cached_ptr); 

你居然與一個共享指針(cached_ptr)開始給定對象,然後創建一個臨時(即帶來的引用計數2)得到又分配給passed_ptr(使參考計數爲3),並最終被破壞(使參考計數回到2)。

在另一方面,如果你想要的是有passed_ptr作爲共享指向對象的副本被指向cached_ptr,那麼你應該寧願做(假設Data是可複製的,當然):

passed_ptr = boost::make_shared<Data>(*cached_ptr); 

,或者:

passed_ptr.reset(new Data(*cached_ptr)); 
+0

我想要一個實際的副本,而不是2個指針指向同一個對象當我修改passed_ptr的數據時,cached_ptr的數據應該保持不變 – Thalia 2013-05-07 16:20:58

+0

@Thalia:我擴展了我的答案來涵蓋這個 – 2013-05-07 16:23:23

+0

謝謝,我在提出這個問題之前看到了這個,並試圖用「重置「,但它不可用 – Thalia 2013-05-07 16:25:56

1

通常的慣例是通過一個const shared_ptr

bool 
someWork(data_ptr const& passed_ptr) 
{ 
    // ... 
} 

這允許使用指示器(包括複製和轉換 ),但不修改它。

如果您想要在呼叫 網站上更改指針指向的內容,則必須傳遞非const引用。這裏最簡單的 政策是,恕我直言,分配新的價值,但你也可以 也叫reset函數。

至於它是如何工作的:當您將指針傳遞給參考 參數時,您只需將被調用的函數訪問到原始指針即 。在引擎蓋下,它非常類似於 這是一個系統地解引用的指針。而你似乎將指針與它指向的內容混淆在一起;它正是它共享的內容,而不是指針本身。指針本身 的行爲與任何其他C++對象完全相同。

+0

我沒能常量,因爲它的內容會改變 - 如果我讓常量,我還可以改變它包含的數據? – Thalia 2013-05-07 16:17:55

+0

@Thalia:你不能改變指針本身的狀態(例如分配),但你可以改變對象的狀態被指向 – 2013-05-07 16:18:37

+0

所以我如何才能複製到passed_ptr的內容cached_ptr的內容 - 沒有分配一個指針到另一個? – Thalia 2013-05-07 16:18:57

9

好的。讓我們看看我們是否可以談論這個。

std::shared_ptr<Data> x = std::make_shared<Data>(); 
std::shared_ptr<Data> y = x; 

assert(x.get() == y.get()); 

如果我改變一些什麼x點,將改變有關y爲好。因爲他們指向相同的東西。

x->member = 3; 
assert(x->member == 3); 
assert(y->member == 3); 

我可以什麼x點改變不改變什麼y點。

x = std::make_shared<Data>(); 
assert(x.get() != y.get()); 

如果我這樣做,然後改到x不會反映在y。因爲他們指向不同的東西。

x->member = 4; 
assert(x->member == 4); 
assert(y->member != 4); 

如果我想打的x內容的副本,並存儲在y,然後我需要創建一個新的共享對象。

y = std::make_shared<Data>(*x); 

在這一點上,無論是xy有一個成員變量設置爲4。由於x有它設置,並且我們與*x內容創建*y

assert(x->member == 4); 
assert(y->member == 4); 

但是,由於xy在內存中指向不同的東西,我們可以改變其中的一個。

assert(x.get() != y.get(); 
x->member = 3; 
assert(x->member == 3); 
assert(y->member == 4); 

如果我要傳遞一個shared_ptr函數,那就像第一個例子。

void func(std::shared_ptr<Data> z) { 
    assert(x.get() == z.get()); 
} 

func(x); 

我還可以通過使用reset()來釋放特定shared_ptr的內容。這會導致shared_ptr指向的值變爲NULL。

x.reset(); 
assert(x.get() == NULL); 

關於常量的正確性,這有點奇怪。

const std::shared_ptr<Data> x; 
x.reset(); // Fails because the shared_ptr is const. 
x->member = 3; // Succeeds because Data is not const. 

std::shared_ptr<const Data> x; 
x.reset(); // Succeeds because the shared_ptr is not const. 
x->member = 3; // Fails because Data is const. 
相關問題