2009-12-08 62 views
6

我試圖設計一個類,它可以更新對一個對象(類之外)的引用銷燬。在c中存儲引用#

所以,基本上你創建了這個對象的一個​​實例,並傳遞給它一個引用類型(以任何方式,構造函數等),然後破壞對象原始引用已經改變爲由對象創建的引用。

如果我通過引用傳遞引用(比如在構造中),我無法想出一個方法來存儲此引用(作爲引用)以供析構函數更新它嗎? 例如(僞):

class Updater 
{ 
    object privateReference; 
    public Updater(ref object externalReference) 
    { 
     privateReference = externalReference; //is privateReference now a new reference to the original object? 
    } 

    ~Updater() 
    { 
     privateReference = new object(); //therefore this isn't 'repointing' the externalReference 
    } 
} 

這裏的關鍵是我並不想發生變異從這個類我想原來的「外部」對象「重新指向」它,或者如果你願意初始化它。

+0

如果你正在銷燬你的物體,爲什麼'重新命名'一個內部字段也會被銷燬呢? – Oded 2009-12-08 11:37:44

+0

即時通訊不試圖重新命名內部領域,這是重點。我試圖重新指出它指向的東西......如果這是有道理的。 – 2009-12-08 11:40:24

+2

將一個字段(或任何其他基於堆的存儲,如數組元素)存儲到一個變量的ref是絕對合法的。原因是:ref可能是堆棧中一個局部變量的引用,它的生存期比存放ref的存儲區更短,從而導致ref無效。我們可以(1)使裁判不安全和脆弱,比如C++,或者(2)限制裁判的存儲並保持裁判總是安全的,或者(3)從不在堆疊中存儲東西。我們選擇了(2)。 – 2009-12-08 14:42:25

回答

7

基本上,你不能這樣做。 ref只適用於該方法本身。

你一直都不清楚你想用什麼 - 你能給我們更多的信息,所以我們可以建議替代設計嗎?任何依賴於終結器的東西都是令人頭痛的,說實話...

+0

正是我害怕的!這是一個我曾經在C++中看到的剖析器的實現...基本上你創建了一個Profiler實例(傳入一個變量,在事件探查器落入範圍之外時,這個變量被充滿(在本例中)是一個時間跨度對象。顯然依靠指針分配... – 2009-12-08 11:43:58

+1

當變量超出範圍時終止器不運行,所以這是它不起作用的另一個原因... – 2009-12-08 11:48:20

1

請注意,使用Finalizer這樣的功能與C++中的析構函數並不相同。

當最後一個參考死亡(也許它超出範圍)時,對象將進入Finalizer隊列。 GC確定何時調用終結器,並且在最後一次參考死亡後很長時間。

4

這將不起作用,因爲構造函數參數的ref方面僅適用於構造函數內部。

我會做的是給構造函數一個委託,可以用來更新有問題的東西。此外,您應該使用IDisposable(與using塊一起)而不是終結器;終結器不應該觸摸託管對象(它們旨在釋放非託管對象)。

class Updater : IDisposable 
{ 
    Action<object> setter; 

    public Updater(Action<object> setter) 
    { 
     this.setter = setter; 
    } 

    public Dispose() 
    { 
     setter(new object()); 
    } 
} 
+0

這實際上是我正在調整的示例的方法需要..這是一個選項,但我想稍微解耦它。 – 2009-12-08 11:45:35