На път съм да създам йерархия на клас изключение, която концептуално изглежда донякъде така:
#include <iostream>
#include <stdexcept>
class ExceptionBase : public std::runtime_error {
public:
ExceptionBase( const char * msg ) : std::runtime_error(msg) {}
};
class OperationFailure : virtual public ExceptionBase {
public:
using ExceptionBase::ExceptionBase;
};
class FileDoesNotExistError : virtual public ExceptionBase {
public:
using ExceptionBase::ExceptionBase;
};
class OperationFailedBecauseFileDoesNotExistError
: public OperationFailure, FileDoesNotExistError {
public:
using ExceptionBase::ExceptionBase; // does not compile
};
int main() {
OperationFailedBecauseFileDoesNotExistError e("Hello world!\n");
std::cout << e.what();
}
Всички конструктори трябва да изглеждат по същия начин като конструктора на класа ExceptionBase
. Изведените изключения се различават само по отношение на техния тип, в противен случай няма добавена функционалност. Последният тип изключение, споменат в горния код, също трябва да има тези конструктори. Възможно ли е това с помощта на функцията за наследяване на конструктори на стандарта C++11? Ако това не е възможно: какви са алтернативите?
(Между другото: В горния код класовете OperationFailure
и FileDoesNotExistError
не се компилираха с gcc 4.8, а с clang 3.4. Очевидно gcc отхвърля наследяващите конструктори за виртуални бази. Би било интересно да знаем кой е прав тук. И двата компилатора отхвърлиха клас OperationFailedBecauseFileDoesNotExistError
, защото наследяващият конструктор не наследява от директна база.)
using OperationFailure::OperationFailure
? Но вероятно няма да работи поради двойното наследяване. - person Albert   schedule 16.10.2013OperationFailure
при създаване на обект (с параметризирания ctor). При замяна на виртуалното наследство с невиртуално, това работи. Предлагам ви да подадете доклад за грешка за gcc, тъй като не мога да намеря нищо в стандарта, което забранява това, и последното предложение N2540 изрично го позволява. - person dyp   schedule 16.10.2013