簡體   English   中英

智能指針和異常處理

[英]Smart Pointers and Exception handling

我已經瀏覽了互聯網,這個主題正在尋找我面臨的這種情況的完整答案。 我已經讀過,向對象投擲智能指針並不是很聰明。 我只是想明白為什么會這樣。 我會解釋一下情況。 讓我們想象一下這個簡單的層次結構

class Foo 
{ 
public: virtual ~Foo() {} 
}; 

typedef tr1::shared_ptr<Foo> SPFoo; 

class FooInherited: public Foo { }; 

typedef tr1::shared_ptr<FooInherited> SPFooInherited; 

讓我們檢查一下這個測試代碼:

int main(int argc, char** argv) 
{ 
  try 
  { 
    throw FooInherited(); 
  } 
  catch(const Foo& f) 
  { 
    cout << "Foo& caught!" << endl; 
  } 
  try 
  { 
    throw SPFooInherited(new FooInherited()); 
  } 
  catch(const SPFoo& f) 
  { 
    cout << "SPFoo& caught!" << endl; 
  } 
  return 0; 
} 

一切都編譯但在運行時第二次try-catch不會被執行。 有人能解釋一下為什么嗎? 特別是如果像這樣的代碼行在運行時完全正常。

void function(const SPFoo& f) 
{ 
} 

... 

SPFooInherited fi(new FooInherited()); 
function(fi);

我確實理解問題是SPFooInherited不從SPFoo繼承(即使FooInherited繼承自Foo),但它深深想知道當捕獲異常時,編譯器/ RTE與函數調用示例的不同之處是什么能夠解決de情況。 是因為catch參數與函數調用參數不同嗎? 為什么Foo&works和SPFoo沒有?

非常感謝你提前。

此致,伊克爾。

當你在你的問題說, SPFooInherited不是一個子類SPFoo 這意味着catch(SPFoo const&)不會捕獲SPFooInherited實例。 另一方面, FooInherited繼承自Foo ,因此catch(Foo const&)將捕獲FooInherited實例。

要理解這一點,您不需要對編譯器或運行時環境有任何特殊的了解。 它只是語言的一部分。

調用函數的原因是tr1::shared_ptr有一個模板化的非顯式構造函數,它允許在函數調用站點進行隱式轉換。

即: tr1::shared_ptr具有以下構造函數:

//Note the lack of explicit
template<class Y> shared_ptr(shared_ptr<Y> const & r);

這允許從不同的共享指針類型構造shared_ptr 此構造函數的實現依賴於從FooInherited*Foo*的隱式轉換,以實際將SPFooInherited的指針存儲到SPFoo 如果此隱式轉換不存在則代碼將無法編譯,因此不會發生shared_ptr與不相關類型之間的不安全轉換。

函數調用和catch之間的根本區別在於隱式轉換將在函數參數的初始化中發生,但catch只能匹配單個類型( FooInherited is-a Foo ,因此它將匹配)。

因為SPFoo不是一個子類SPFooInherited catch塊只會捕獲捕獲列表中的內容,或者捕獲列表中的內容的公共子類。 FooInheritedFoo ,因此捕捉Foo也會讓你抓住FooInherited SPFooSPFooInherited是完全不同SPFooInherited相關的類。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM