2010-02-07 83 views
3

我想製作一個名爲「Person」的我自己的對象類的全局向量。然而,編譯器說,C++ Ref類不是System :: IDisposable的成員;麻煩實施IDisposable

error C2039: '{dtor}' : is not a member of 'System::IDisposable' 
1>  c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable' 

於是我擡起頭來如何實現IDisposable(我現在知道的是主要用於非託管資源),但似乎仍然無法與以下實現它:

ref class Globals : System::IDisposable 
{ 
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>; 
    void Dispose() 
    { 
     delete person_data; 
    } 
}; 

的2個錯誤,我得到的是:

error C2605: 'Dispose' : this method is reserved within a managed class 
1>  did you intend to define a destructor? 
error C3766: 'Globals' must provide an implementation for the interface method 'void System::IDisposable::Dispose(void)' 
1>  c:\windows\microsoft.net\framework\v2.0.50727\mscorlib.dll : see declaration of 'System::IDisposable::Dispose' 

回答

-1

C++/CLI中行動的C++/CLI處置圖案具有這些規則(轉述):

  • 如果類具有一個終結或編譯器生成的 析構函數 Dispose(bool)將根據 ,bool值調用 終結器或析構函數。
  • 如果它只有一個(〜型),那麼編譯器會調用 Dispose(true),這樣調用者就會被調用。
  • 如果它只是一個終結 那麼編譯器調用 的Dispose(假),這樣終結的 叫

對於第二規則(類型!):編譯器將實現IDisposable接口讓您(通過生成Dispose())。然後它使用SuppressFinalize來確保終結器未被調用。

我這樣做了你的代碼,我可以讓它編譯的唯一方法是使person_data成爲一個實例成員。我在靜態時得到的錯誤是error C2039: '{dtor}' : is not a member of 'System::IDisposable',這沒有多大意義。

另外,你甚至需要delete person_data向量,因爲它是一個託管對象嗎?也許你會這樣做,但我還沒有使用足夠的說法。

編輯也許這article第一款有答案(重點煤礦):

在聲明成員變量 靜態和當應用程序 開始,編譯器創建的副本 該成員。當編譯器運行 程序時,該成員將爲 。如果您聲明一個類的 例如,像上面 車輛變量,靜態成員是 對象的不部分:編譯 創建和維護靜態 成員,無論您使用與否, 是否你聲明一個類變量 或不。

+0

感謝您的回覆,我認爲這確實會有訣竅。不知道爲什麼那個析構錯誤不斷出現。 – Dororo 2010-02-08 18:47:04

+0

我似乎無法找到關於釋放析構函數或終結器中的靜態成員的任何信息。也許有人在那裏知道答案並將分享。 – cmw 2010-02-08 19:01:00

+0

靜態成員由.cctor初始化,而不是在應用程序啓動時初始化 – 2010-02-23 16:22:03

0

使用析構函數。在C++/CLI中〜ClassName()是Dispose()和!ClassName()等同於C#的〜ClassName()。你的情況:

ref class Globals : System::IDisposable 
{ 
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>; 
    void ~Globals() 
    { 
     delete person_data; 
    } 
}; 
+0

編譯器然後說析構函數不能有返回類型。然而,刪除'void'會使編譯器無法將該函數識別爲IDisposable的實現(因爲它的形式可能是void func(void)?) – Dororo 2010-02-07 18:00:14

3

所示的終結不必明確自IDisposable派生。繼MSDN doco,使用下列模式:

ref class Globals 
{ 
public: 
    static cliext::vector<Person^> person_data = gcnew cliext::vector<Person^>; 
    !Globals() // finalizer 
    { 
     delete person_data; 
    { 
protected: 
    ~Globals() // destructor calls finalizer 
    { 
     this->!Globals(); 
    } 
}; 
+0

感謝您的幫助,但我仍然收到以下錯誤消息: static cliext :: vector person_data = gcnew cliext :: vector ; 編譯器指出析構函數不是IDisposable的成員: 1>錯誤C2039:'{dtor}':不是'System :: IDisposable'的成員 1> c:\ windows \ microsoft.net \ framework \ v2.0.50727 \ mscorlib.dll:請參閱'System :: IDisposable'聲明 即使確保Person類確實是IDisposable,它仍然拒絕編譯。 – Dororo 2010-02-08 07:16:45

+0

我可以編譯的唯一方法是從person_data中刪除'static'關鍵字。只要你有一個類型cliext :: vector 的靜態成員,你會得到這個錯誤 - 我試圖刪除person_data並用cliext替換它:: vector int_data = gcnew cliext :: vector ;並仍然有相同的錯誤!它超出了我的技能。 – mcdave 2010-02-08 11:45:32

+0

你不能刪除什麼不是句柄 – 2010-02-23 16:18:33

0

您不需要直接或通過析構函數自己實現Dispose()。隱式生成的析構函數已經銷燬所有成員對象。 IDisposable接口將自動添加,不要明確提及它。接下來,您需要下定決心person_data是一個句柄(必須設置爲使用gcnew創建的實例)還是成員對象語義(如堆棧語義,構造函數會自動由父對象,在父對象的生命週期結束時自動調用析構函數,並且使用「。」而不是「 - >」來訪問成員)。

另外,你確定你想要在所有「Globals」實例之間共享person_data的一個拷貝,但是被第一個實例銷燬,留下任何持有無效引用的其他實例(引用已處理對象)?它看起來像你試圖在這裏使用Singleton反模式,這是正確的嗎?