在派生类中扩展枚举

Bri*_*per 12 c++ inheritance

我有一个类层次结构,其中的每个类都有一个异常类,派生在并行层次结构中,因此......

class Base
{
};

class Derived : public Base
{
};

class BaseException : public std::exception
{
   enum {THIS_REASON, THAT_REASON};
};

class DerivedException : public BaseException
{
    // er...what?
};
Run Code Online (Sandbox Code Playgroud)

我想在DerivedException类中扩展枚举类型以包含新值THE_OTHER_REASON,以便DerivedException类可以包含三个值中的任何一个.

首先,我应该这样做吗?这似乎是一种合理的做法吗?如果是这样,我该怎么做呢?如果没有,你会推荐哪些替代品?

编辑:这里建议可能重复,但建议的解决方案是不同的,因为这个问题是C#和C++的问题.

Pét*_*rök 11

从OO的角度来看,这是不合理的.既然你说的DerivedException 是-a BaseException,它的可能原因必须是其中的一个子集,而BaseException不是超集.否则你最终打破Liskov替代原则.

此外,由于C++枚举不是类,因此无法扩展或继承它们.您可以在单独的枚举中定义其他原因DerivedException,但最终会遇到上述相同的问题:

class DerivedException : public BaseException
{
  enum {
    SOME_OTHER_REASON = THAT_REASON + 256, // allow extensions in the base enum
    AND_ANOTHER_REASON
  };
  ...
};

...
try {
  ...
} catch (BaseException& ex) {
  if (ex.getReason() == BaseException::THIS_REASON)
    ...
  else if (ex.getReason() == BaseException::THAT_REASON)
    ...
  else if (ex.getReason() == ??? what to test for here ???)
    ...
}
Run Code Online (Sandbox Code Playgroud)

你可以做的是为每个不同的原因定义一个单独的异常子类.然后你可以多态地处理它们(如果需要的话).这是标准C++库以及其他类库的方法.因此,您遵守惯例,这使您的代码更容易理解.


Bar*_*nau 9

对我来说,为每个异常原因设置一个异常类似乎更合理.处理异常时,知道哪个类抛出异常通常没有意义,但抛出异常的原因是什么.

如果你想保留你的设计:C++不允许你扩展现有的枚举,但你可以创建一个新的枚举,从前一个枚举开始:

class BaseException : public std::exception
{
   enum {THIS_REASON, THAT_REASON, END_OF_BASE_REASONS };
};

class DerivedException : public BaseException
{
   enum {OTHER_REASON = BaseException::END_OF_BASE_REASONS };
};
Run Code Online (Sandbox Code Playgroud)