2015-12-07 70 views
1

我有一個基本異常類(其中包括)流媒體運營商:重載的操作符返回對基類的引用,如何返回對派生類的引用呢?

Base& Base::operator<<(const std::string& str); 

此運算符返回*this

我有幾個派生類看起來像:

class Derived : public Base { }; 

在某些時候,我創建並拋出從基地派生的類。喜歡的東西:

try 
{ 
    [...] 
} 
catch(Derived& ex) 
{ 
    [...] 
} 

什麼是這樣做的最佳方式:

std::string myStr("foo bar"); 
throw Derived() << myStr; 

我想用捕獲此異常?在投擲之前將基地投入派生可以嗎?我可以將基類更改爲模板而不是定義這些派生類嗎? [...]?

回答

3

問題出在throw關鍵字,不在返回的引用中。該參考很好地指向基類和派生類。它是throw關鍵字,它使用聲明的類型而不是拋出的對象的多態類型。要拋出異常的多態類型,可以使用Polymorphic Exception C++ idiom。您需要在基類中聲明虛擬Raise()方法,然後使用實現throw *this;覆蓋派生類中的方法。在這種情況下,在派生類中,除非您忘記在某些派生類中忽略Raise()方法,否則參考*this的聲明類型將與其多態類型匹配。

+0

有趣的閱讀。感謝您的鏈接。 – Lieuwe

1

我會稍微重新安排您的代碼,以便插入運算符在任何異常類之外。

class StringBuilder 
{ 
public: 
    template<class T> 
    StringBuilder& operator<<(const T& t) 
    { 
     ss_ << t; 
     return *this; 
    } 

    operator std::string() const 
    { 
     return ss_.str(); 
    } 

private: 
    std::stringstream ss_; 
}; 

class Base : public std::runtime_error 
{ 
    using runtime_error::runtime_error; 
}; 

class Derived : public Base 
{ 
    using Base::Base; 
}; 

int main() 
{ 
    try 
    { 
     throw Derived(StringBuilder() << "hello world"); 
    } 
    catch(const Derived& e) 
    { 
     std::cout << "Derived\n"; 
    } 
    catch(const Base& e) 
    { 
     std::cout << "Base\n"; 
    } 
    return 0; 
} 
相關問題