Возможно ли писать свободно используемые методы chanining, возвращающие производный тип? Рассмотрим следующие два класса:метод цепочки с полиморфизмом C++
class Base {
protected:
std::string mFoo;
public:
Base& withFoo(std::string foo) {
mFoo = foo;
return *this;
}
};
class Derived : public Base {
protected:
std::string mBar;
public:
Derived& withBar(std::string bar) {
mBar = bar;
return *this;
}
void doOutput() {
std::cout << "Foo is " <<
mFoo << ". Bar is " <<
mBar << "." << std::endl;
}
};
Я тогда хотел бы построить свой объект и использовать его как это:
Derived d;
d.withFoo("foo").withBar("bar").doOutput();
Это, конечно, не удается, так как withFoo
возвращает Base
. Поскольку все мои методы with
просто устанавливают переменные-члены, я могу сначала указать производные with
. Проблема заключается в том, что мой метод построения (doOutput
в приведенном выше примере) должен быть отдельным заявлением.
Derived d;
d.withBar("this is a bar")
.withFoo("this is my foo");
d.doOutput();
Мой вопрос, есть ли какой-нибудь способ для withFoo
вернуть неизвестный производный тип, так что Base
может быть использован без проблем с несколькими производными классами (в конце концов, *this
являетсяDerived
, хотя Base
(правильно) не знает об этом).
Для более конкретного примера я пишу несколько классов для доступа к серверу REST. У меня есть класс RestConnection
с методом withUrl
, a PostableRest
класс с методами withParam
и doPost
и класс GettableRest
с doGet
. Я подозреваю, что это невозможно, и, вероятно, попробуем переделать кучу виртуальных методов в RestConnection
, но я не люблю это делать, когда перегружено несколько withParam
s, некоторые из которых не имеют смысла включать в список параметров GET.
Заранее благодарен!
Вы можете указать базовый параметр шаблона, а Derived передать себя как параметр, когда он наследует базу. Теперь Base может вернуть ссылку на этот параметр шаблона. –
Вас может заинтересовать Decorator pattern. – Jarod42
Вам также нужен полиморфизм времени выполнения от 'Base' до различных производных классов? Также обратите внимание, что в целом защищенные атрибуты (а не методы) являются сильным дизайнерским запахом, поскольку они допускают легкое нарушение инвариантов. –