У нас есть базовая ситуация, которая выглядит, как выглядит следующим образом:Укажите дополнительный базовый тип в иерархии исключений на C++?
// 3rd party lib:
namespace ns3p {
class OperationException : public std::exception; // yes, no `virtual` here
}
// our code:
// wrapper with additional information to the ns3p::OperationException
class ModuleOpException : public ns3p::OperationException;
// our catch sites:
// mostly:
catch (ModuleOpException const& ex) { ...
// but sometimes:
catch (ns3p::OperationException const& ex) { ...
Теперь этот вырос, чтобы включить дополнительные исключения, все полученные из ModuleOpException
, что не имеют ничего общего с какими-либо ошибками от 3 участника lib, но их просто бросают в том же контексте, где используются материалы из сторонней библиотеки lib.
// This indirectly derives from ns3p::OperationException, even though
// there is *no* underlying OperationException at all. It just thrown "stand alone"
// and caught by ModuleOpException& :
class InvalidXYZException : public ModuleOpExcpetion;
Теперь мы думали о «переворачивания» иерархии, чтобы лучше отражать реальную ситуацию и сделать это с (первоначально) минимальным воздействием на другой код.
Мы планируем сделать это:
// new base exception type:
class ModuleBaseException : public virtual std::exception;
// changed to derive both from our base type as well as the 3rd party type:
class ModuleOpException : public virtual ModuleBaseException, public virtual ns3p::OperationException;
// only derives from the base type:
class InvalidXYZException : public virtual ModuleBaseException;
// all catch sites change the catch of `ModuleOpException` to:
catch (ModuleBaseException const& ex) { ...
// and leave the catch ns3p::OperationException alone
Это должно работать (? Надо это), за исключением того, что я не знаю, сколько не-виртуальное наследование от std::exception
3-й части типа исключения может испортить вещи. I думаю мы безопасны as long as noone tries to catch(std::exception const&)
in which case the catch would fail для привязки во время выполнения, потому что преобразование неоднозначно.
Это похоже на жизнеспособное решение? Или это «действительно плохая идея», чтобы попытаться интегрировать тип non-virtual-std::exception
с иерархией, как указано выше?
Примечание: Существует нулевой шанс (как в 0.00%
), что мы можем когда-либо изменить 3-й партии LIB, чтобы получить «правильно» с virtual
от станд :: исключением.
- Конечно, если какой-либо
catch(ns3p::OperationException&)
в предыдущей версии «случайно» перехваченаInvalidXYZExecption
это сломается сейчас, но это было бы приемлемо.
Зачем вам так много классов исключений и зачем вам ModuleOpException вывести из класса исключений из сторонней библиотеки? – CashCow