簡體   English   中英

復制boost :: shared_ptr

[英]Copy boost::shared_ptr

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
}

我查看了文檔;

復制和轉換構造函數

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會去哪里? 他們分享所有權意味着什么? 那么它不是副本,如果我修改“pass_ptr”,更改會影響“cached_ptr”嗎?

我找不到例子......請幫忙。

謝謝。

好吧,如果你有一個shared_ptr並將它分配給另一個shared_ptr ,那么這兩個共享指針將共享對象的所有權 - 這意味着指向對象所有權的引用計數將增加1。

實際上,在上面的行中,您根本不需要構造臨時共享指針。 這就夠了:

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));

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

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正確性,它有點奇怪。

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.

通常的慣例是傳遞const shared_ptr

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

這允許使用指針(包括復制和轉換它),但不能修改它。

如果要更改指針指向調用站點的內容,則必須傳遞非const引用。 這里最簡單的策略是,恕我直言,為它分配新值,但你也可以調用reset功能。

至於它是如何工作的:當你將指針傳遞給引用參數時,你只需要給被調用函數訪問原始指針。 在引擎蓋下,它非常像一個系統地解除引用的指針。 你似乎把指針與它指向的東西混淆了; 它指向的是共享,而不是指針本身。 指針本身的行為與任何其他C ++對象完全相同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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