具有多态性的方法链 C++

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 的类withParamdoPost以及一个GettableRest带有doGet. 我怀疑这是不可能的,并且可能会尝试塞入一堆虚拟方法RestConnection,但是当有多个withParam重载时我讨厌这样做,其中一些方法包含在 GET 参数列表中是没有意义的。

提前致谢!

Mar*_*k B 5

我认为你可以在这里利用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)