В этом надуманном примере:
struct point_2d {
point_2d& x( int n ) {
x_ = n;
return *this;
}
point_2d& y( int n ) {
y_ = n;
return *this;
}
int x_, y_;
};
struct point_3d : point_2d {
point_3d& z( int n ) {
z_ = n;
return *this;
}
int z_;
};
int main() {
point_3d p;
p.x(0).y(0).z(0); // error: "point_2d" has no member named "z"
return 0;
}
идея состоит в том, чтобы использовать «цепочку функций-членов», чтобы иметь возможность вызывать более одной функции-члена подряд. (Есть много примеров этого; приведенный выше - самый короткий, который я мог придумать, чтобы задать этот вопрос. Моя реальная проблема аналогична и описана ниже.)
Проблема в том, что если производный класс добавляет свой собственные цепочки функций-членов, но вы сначала вызываете функцию-член базового класса, вы получаете ссылку на базовый класс, которая, конечно, не будет работать для вызова функции-члена производного класса.
Есть ли какие-нибудь умные способы решить эту проблему и по-прежнему поддерживать возможность связывания функций-членов?
Моя настоящая проблема заключается в том, что мой базовый класс является исключением а мой производный класс - это класс, производный от базового исключения. Для этих классов также я хочу использовать цепочку функций-членов:
class base_exception : public std::exception {
// ...
base_exception& set_something( int some_param ) {
// ...
return *this;
}
};
class derived_exception : public base_exception {
// ...
};
int main() {
try {
// ...
if ( disaster )
throw derived_exception( required_arg1, required_arg2 )
.set_something( optional_param );
}
catch ( derived_exception const &e ) {
// terminate called after throwing an instance of 'base_exception'
}
}
Проблема в том, что set_something ()
возвращает base_exception
, но catch
ожидает производное_исключение
. Конечно, человек может сказать, что фактическим типом исключения является производное_исключение
, но компилятор явно не может сказать.
Это проблема, которую я действительно пытаюсь решить , т.е. как сделать так, чтобы базовый класс исключения мог устанавливать необязательные параметры для объекта исключения, но при этом возвращал экземпляр производного типа. Пример point_2d
, который я привел выше, является (я считаю) уменьшенной и более простой версией той же проблемы, которую люди могут понять, и что решение меньшей проблемы также решит мою настоящую проблему.
Обратите внимание, что Я действительно думал о том, чтобы сделать base_exception
шаблоном и передать производный тип, например:
template<class Derived>
class base_exception {
// ...
Derived& set_something( int some_param ) {
// ...
return *this;
}
};
Я считаю, что это действительно решает проблему, но это не идеальное решение, потому что если другой класс more_dehibited_exception
происходит от производного_исключения
, то мы возвращаемся к той же проблеме.