【问题标题】:Overloaded operator returns reference to base class, how to return a reference to the derived class instead?重载运算符返回对基类的引用,如何改为返回对派生类的引用?
【发布时间】:2015-12-07 16:51:11
【问题描述】:

我有一个带有(以及其他)流操作符的基本异常类:

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) 
{ 
  [...] 
}

这样做的最佳方式是什么?在投掷之前将 Base 转换为 Derived 可以吗?我可以将基类更改为模板而不是定义这些派生类吗? [...]?

【问题讨论】:

    标签: c++ inheritance


    【解决方案1】:

    问题出在throw 关键字中,而不是在返回的引用中。引用很好地指向基类和派生类。 throw 关键字使用声明的类型而不是要抛出的对象的多态类型。要抛出异常的多态类型,可以使用Polymorphic Exception C++ idiom。您需要在基类中声明一个虚拟的Raise() 方法,然后在派生类中用实现throw *this; 覆盖该方法。在这种情况下,在派生类中,引用 *this 的声明类型将匹配其多态类型,除非您忘记在某些派生类中重写 Raise() 方法。

    【讨论】:

      【解决方案2】:

      我会稍微重新排列您的代码,以便插入运算符位于任何异常类之外。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-13
        • 1970-01-01
        • 2020-07-09
        • 2014-03-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多