簡體   English   中英

重載的運算符返回對基類的引用,如何返回對派生類的引用呢?

[英]Overloaded operator returns reference to base class, how to return a reference to the derived class instead?

我有一個基本的異常類,以及其他的流運算符:

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

該運算符返回*this

我有幾個派生類,如下所示:

class Derived : public Base { };

在某個時候,我創建並拋出了一個從Base派生的類。 就像是:

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

我想使用以下方法捕獲此異常:

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

這樣做的最佳方法是什么? 可以在拋出基礎之前將基礎鑄造為“派生”嗎? 我可以將基類更改為模板,而不是定義這些派生類嗎? [...]?

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

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

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;
}

暫無
暫無

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

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