asm*_*ean 3 c++ polymorphism fluent
是否可以编写返回派生类型的流畅的处理方法?考虑以下两个类:
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;
}
};
Run Code Online (Sandbox Code Playgroud)
然后我想构建我的对象并像这样使用它:
Derived d;
d.withFoo("foo").withBar("bar").doOutput();
Run Code Online (Sandbox Code Playgroud)
这当然会失败,因为withFoo返回一个Base. 由于我的所有with方法都只是设置成员变量,因此我可以首先指定派生的withs。问题是我的构建器方法(doOutput在上面的示例中)需要是一个单独的语句。
Derived d;
d.withBar("this is a bar")
.withFoo("this is my foo");
d.doOutput();
Run Code Online (Sandbox Code Playgroud)
我的问题是是否有某种方法可以withFoo返回未知的派生类型,以便Base可以与多个派生类无缝使用(毕竟,*this 是a Derived,尽管Base(正确地)不知道这一事实)。
对于更具体的示例,我正在编写一些类来访问 REST 服务器。我有一个RestConnection带有 method 的类withUrl,一个PostableRest带有 method 的类withParam,doPost以及一个GettableRest带有doGet. 我怀疑这是不可能的,并且可能会尝试塞入一堆虚拟方法RestConnection,但是当有多个withParam重载时我讨厌这样做,其中一些方法包含在 GET 参数列表中是没有意义的。
提前致谢!
我认为你可以在这里利用CRTP,如下所示,其中派生类告诉基类它是什么类型:
class Base
{
// Abstract/virtual interface here.
};
template <class Derived>
class Base_T : public Base
{
private:
std::string mFoo;
public:
Derived& withFoo(std::string foo) {
mFoo = foo;
return *static_cast<Derived*>(this);
}
};
class Derived : public Base_T<Derived> {
private:
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;
}
};
Run Code Online (Sandbox Code Playgroud)