yegor256
yegor256

Reputation: 105143

How to implement fluent interface with a base class, in C++

How can I implement this fluent interface in C++:

class Base {
public:
  Base& add(int x) {
    return *this;
  }
}

class Derived : public Base {
public:
  Derived& minus(int x) {
    return *this;
  }
}

Derived d;
d.add(1).minus(2).add(3).minus(4);

Current code doesn't work since Base class doesn't know anything about Derived class, etc. I would be very thankful for a hint/suggestion.

Upvotes: 6

Views: 1005

Answers (3)

Vicente Botet Escriba
Vicente Botet Escriba

Reputation: 4345

The problem is on your function

  Base& add(int x); 

This is similar to the operator+=(), which must also be overridden to work seamless.

You need to override this function on the derived class.

class Derived : public Base {
public:
  Derived& minus(int x) {
    return *this;
  }
  Derived & add(int x) {
    return  static_cast<Derived &>(this->Base::add(x));
  }
}

in this way d.add(1) will return a reference to d.

Upvotes: 1

Patrick
Patrick

Reputation: 23629

Make Base class templated. Use the wanted return type of Base the template type, like this:

template <typename T>
class Base {
public:
  T& add(int x) {
    return *static_cast<T *>(this);
  }
}

Then inherit Derived from Base like this:

class Derived : public Base<Derived>

Alternatively (as an answer to Noah's comment), if you don't want to change Base, you could use an intermediate class that performs the casting, like this:

template <typename T>
class Intermediate : public Base {
public:
  T& add(int x) {
    Base::add(x);
    return *static_cast<T *>(this);
  }
}

And let Derived inherit from Intermediate:

class Derived : public Intermediate<Derived>

Upvotes: 12

Edward Strange
Edward Strange

Reputation: 40877

This interface is not possible in C++. You must either make minus() a virtual function within Base or use non-member functions that do some form of type detection.

Don't pull up minus() unless it makes sense in terms of Base.

Upvotes: 0

Related Questions