2014-10-12 146 views
0

設置一個指針有沒有辦法做到:刪除,並在同一指令

A* a1 = /*something*/; 
A* a2 = /*something else*/; 
A* tmp = a1; 
a1 = a2; // both a1 and a2 points to "something else" 
delete tmp; // "something" is deleted 

在一個單獨的語句,其中設置首先做什麼?類似的東西:

A* a1 = /*something*/; 
A* a2 = /*something else*/; 
set_and_delete(a1, a2); // ok 

,設置來的拳頭,而不是做這對我很重要:

delete a1; 
a1 = a2; 

(如果需要的話,我可以解釋爲什麼,但似乎前面的例子就足以理解這個問題)

+0

這是智能指針是(除其他事項外)。 – 2014-10-12 00:09:28

+1

但是,真的不清楚爲什麼排序在這裏很重要。 – 2014-10-12 00:09:55

+0

例如:一個列表。你會做 a1 = a1.nexta1,所以如果a1在復位之前被刪除,它會出錯 – 2014-10-12 00:11:14

回答

3

智能指針像unique_ptr有一個成員函數這個確切的情況:

a1.reset(a2); // assuming a2 is a raw pointer 

a1 = std::move(a2); // If a2 is also a unique_ptr. 

對於你將不得不寫一個合適的函數模板通常原始指針:

template <typename T> struct identity {using type=T;}; 

template <typename T> 
void set_and_delete(T*& ptr, typename identity<T>::type* new_val) 
{ 
    auto tmp = ptr; 
    ptr = new_val; 
    delete tmp; 
} 

注意我們如何使第二個參數的非推斷上下文,以確保沒有抵扣發生衝突。儘管如此,cv-qualifiers仍然可以正常工作。

+0

假設'a2'也是一個智能指針,那麼你可以做'a1 = a2;'。 – 2014-10-12 00:12:58

+0

@OliverCharlesworth你將不得不「移動」 - 但是。 – Columbo 2014-10-12 00:13:47

+0

啊,是的,在'unique_ptr'的情況下,你是對的。 – 2014-10-12 00:15:30

0

你說:「在相同的指令」,這讓我覺得你想使用線程在這裏做一些事情。像原子刪除並設置爲nullptr操作。

如果是如此,關鍵是不要刪除,並在準確的同時設置。技巧是原子指針更新。我相信std::atomic C++庫可以幫助你。你想compare_exchange_strong()

創建TMP變量設置爲0複製要刪除到名爲pointer_expected另一個變量的指針的值。檢查它是否爲0.現在將指針和tmp的值與期望值設置爲pointer_expected。

我相信,這將導致你的指針設置爲零,並獲得在TMP指針的前值則這將是安全的刪除。如果另一個線程已經完成了這個操作,您將得到一個零值,這與您的期望值不符,您將知道不要刪除它。