繁体   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