2014-12-04 79 views
1

我一直在通過閱讀一些現有的代碼來進行一些代碼學習。我知道在非COM類型的接口上使用虛擬析構函數的重要性。我的意思是不是從IUKOWN或IInspectable派生出來的。IUknown Derived接口上的虛擬析構函數

但是,我無法理解爲什麼它不需要在COM接口上具有虛擬析構函數。

我已經定義了這樣的

MIDL_INTERFACE("0D70D782-809D-403B-AC95-XXXXXX") 
IMyInterface : IUnknown 
{ 
    public: 
     virtual bool method1() = 0; 
     virtual int method2() = 0; 
} 

我的界面,並在同一時間我有犯規從IUnkown得出這樣

class ISampleLogic 
    { 
     public: 
     virtual ~ISampleLogic() {}; 
     //some more methods 

    } 

爲什麼沒有用於第一界面沒有虛析構函數的另一個接口?

預先感謝

+1

通常,如果您不打算在接口上調用delete,則「接口」沒有虛擬析構函數是可以的。雖然,如果是這樣的話[可能是好的做法](http://www.gotw.ca/publications/mill18.htm)有一個受保護的析構函數。 – 2014-12-04 08:56:37

回答

2

IUnknown有一個稱爲Release()方法。其工作是減少對象的參考計數,並在參考計數降至零時銷燬該對象。所以它作爲析構函數。因此不需要顯式析構函數。

如果你有一個IUnknown指針(說IUnknown* punk),你不應該delete,但調用Release()代替(punk->Release())。這是因爲其他進程可能會在對象上引用計數。

這是下降到執行的接口,以確保整個對象被刪除。如有必要,該實現可能包含具有虛擬析構函數的類。

+0

感謝您的回覆,但punk-> Release()內部調用本身的刪除(punk)。 (刪除這個)。在這一點上,我們也正在調用delete,並且可能會遇到在Non com接口上調用的同樣的刪除問題。這是否意味着在非com接口中,在接口引用上調用delete並在com接口中對具體類引用調用delete?因此我們不會陷入這個問題。對不起,只是想在我的腦海中清除它。 – virusrocks 2014-12-04 08:32:10

+0

「punk-> Release()內部調用本身的刪除(punk)。(刪除此)」。你確定知道嗎?那麼用C++以外的語言編寫的COM對象呢? – Bathsheba 2014-12-04 08:37:45

+0

它的實現和語言相關,但最終它會像在相應的語言中刪除自己一樣。那就是我爲什麼這麼說的。 – virusrocks 2014-12-04 08:39:45

4

你的第一個代碼片段定義了一個接口,另一個定義了一個不是接口的類(即使你把它稱爲「另一個接口」)。

MSDN

  • 可以從零個或多個基站接口繼承:

    一個Visual C++接口可以被定義如下。

  • 無法從基類繼承。
  • 只能包含公共純虛方法。
  • 不能包含構造函數,析構函數或運算符。
  • 不能包含靜態方法。
  • 不能包含數據成員;屬性是允許的。

長話短說,接口不需要,並且不允許有虛析構函數。它是負責構建和銷燬的託管實現,COM接口定義是一組方法及其語法的契約。

+0

我同意,我會補充說應該用IDL或VC++擴展COM關鍵字來定義接口。 – acelent 2014-12-04 20:09:34