Reputation: 105143
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
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
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
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