2009-01-22 50 views
2

我知道我也沒有問這個問題。請幫助我更好地形成我的問題。如何處理C++/CLI中的句柄?

我有點困難讓我的思緒纏繞手柄 - 在某些方面,它看起來像指針。但是與指針不同的是,我似乎可以直接將值賦給句柄變量,並且它影響底層數據值,而不是句柄本身。

測試代碼清楚地表明,無論使用句柄還是「取消引用」句柄以獲取數據,我都可以獲得相同的值。顯然,這不適用於非託管指針。我不瞭解什麼?

#include <iostream> 

int main() 
{ 

    int ^y; 
    int ^a, ^b, ^c; 
    long x; 

    y= gcnew int(100); 
    a=y; 
    b=y; 
    c=y; 

    c= gcnew int(200); 
    b= 300; 

    System::Console::WriteLine(y); // returns 100 (instead of something pointer-like) 
    System::Console::WriteLine(*y); // also returns 100 

    System::Console::WriteLine(a); // 100 
    System::Console::WriteLine(b); // 300 
    System::Console::WriteLine(c); // 200 

    x = static_cast<long>(y); 
    *y = 10; 

    System::Console::WriteLine(x); // 10 
    System::Console::WriteLine(y); // 10 
    System::Console::WriteLine(*y); // 10 

    } 

編輯補充 - 我懷疑WirteLine可能已經爲我做過的提領,但我本來期望靜態投長期不會。這跟autllboxing有關嗎?

回答

4

C++/CLI允許這種語法有點令人傷心。 int類型是一個值類型,帽子用於引用類型。你的「y」變量不存儲一個int,它存儲System :: Object。編譯器會在您分配它時自動生成一個裝箱指令。 Console :: WriteLine()否則沒有問題顯示一個盒裝int值的對象。

經驗法則:當它是一個類對象時使用帽子,省略它用於簡單的值類型。避免引用類型的堆棧語義(省略帽子,以便在範圍結束時自動調用析構函數),直到您真正理解值類型和引用類型之間的差異以及爲什麼Dispose()很重要。

2

使用WriteLine的副作用。

只是'y'被視爲'對象引用',可能被IFormattable查詢,然後對其調用ToString()。 '* y'傳遞一個int。

爲了測試這個,創建另一個函數調用Foo(int ^)並查看允許哪些內容進入,然後將其更改爲'Foo(int)'。

我想你只是被WriteLine的'可變參數'特性所迷惑。

2

不要依賴WriteLine來告訴你什麼* y和y,從調試器運行它並自己檢查* y和y以查看差異。

0

將句柄看作值類型,就像您可能自己編寫的智能句柄一樣,該句柄具有運算符重載以進行轉換。這樣,使用可以提供int的句柄可以工作(通過轉換運算符)以及取消引用句柄以獲取對象中包含的int。

關於Writeline,我認爲它就像流輸出操作符一樣,隱式調用了許多轉換。就像你可能會安全地使用cout < < y一樣,你可以編寫System :: Console :: WriteLine(y)。