Fluent interfaces and inheritance in C++ - c++

I'd like to build a base (abstract) class (let's call it type::base) with some common funcionality and a fluent interface, the problem I'm facing is the return type of all those methods
class base {
public:
base();
virtual ~base();
base& with_foo();
base& with_bar();
protected:
// whatever...
};
Now I could make subtypes, e.g.:
class my_type : public base {
public:
myType();
// more methods...
};
The problem comes when using those subtypes like this:
my_type build_my_type()
{
return my_type().with_foo().with_bar();
}
This won't compile because we're returning base instead of my_type.
I know that I could just:
my_type build_my_type()
{
my_type ret;
ret.with_foo().with_bar();
return ret;
}
But I was thinking how can I implement it, and I've not found any valid ideas, some suggestion?

This problem of "losing the type" can be solved with templates - but it's rather complicated.
Eg.
class Pizza
{
string topping;
public:
virtual double price() const;
};
template <class T, class Base>
class FluentPizza : public Base
{
T* withAnchovies() { ... some implementation ... };
};
class RectPizza : public FluentPizza<RectPizza, Pizza>
{
double price() const { return length*width; :) }
};
class SquarePizza : public FluentPizza<SquarePizza, RectPizza>
{
... something else ...
};
You can then write
SquarePizza* p=(new SquarePizza)->withAnchovies();
The pattern is that instead of
class T : public B
you write
class T : public Fluent<T, B>
Another approach could be not to use fluent interface on the objects, but on pointers instead:
class Pizza { ... };
class RectPizza { ... };
class SquarePizza { ... whatever you might imagine ... };
template <class T>
class FluentPizzaPtr
{
T* pizza;
public:
FluentPizzaPtr withAnchovies() {
pizza->addAnchovies(); // a nonfluent method
return *this;
}
};
Use like this:
FluentPizzaPtr<SquarePizza> squarePizzaFactory() { ... }
FluentPizzaPtr<SquarePizza> myPizza=squarePizzaFactory().withAnchovies();

You should be returning references/pointers, and you should not need to keep the type information.
class base {
public:
base();
virtual ~base();
base &with_foo();
base &with_bar();
protected:
// whatever...
};
class my_type : public base {
public:
my_type();
// more methods...
};
base *build_my_type()
{
return &new my_type()->with_foo().with_bar();
}
You already have a virtual destructor. Presumably you have other virtual functions. Access everything through the base type and the virtual functions declared there.

One solution would work like this:
return *static_cast<my_type*>(&my_type().with_foo().with_bar());
Using static_cast basically tells the compiler 'I know what I'm doing here'.

In C++ you should be returing pointers or references rather than values. Also, you might want to explain what you mean by "fluent interfaces".

The way I'd do it in C#, and I believe it would work in C++ too is to provide a default implementation for with_foo() and with_bar()... Forgive my c#, but:
class base {
virtual base with_foo()
{ throw new NotImplementedException(); }
virtual base with_bar();
{ throw new NotImplementedException(); }
}

Related

C++ force implementation of method in child class but with a different signature

Is there a way to force implementation of a method in a child class where the implementation will have a different signature for each derived class?
I know I can do this, using pure virtual:
class Base {
public:
virtual void getValue(string& s) = 0;
}
class Derived : public Base {
public:
void getValue(string& s);
}
Above, pure virtual getValue in the base class forces the derived class to implement getValue. But what I really want to do is something like this: Force each derived class to implement getValue() but each with a different signature:
class Base {
public:
void getValue() = 0;
}
class Derived_A : public Base {
public:
void getValue(string& s);
}
class Derived_B : public Base {
public:
void getValue(int *j);
}
The problem with the above is that, due to name mangling, each signature is effectively a different function, and thus Derived_A and Derived_B inherit getValue() = 0 and the compiler thinks that they also are abstract.
I've been playing around with some different ways to do this, but it appears to me there is no way to do it. I'm thinking I should simply not declare getValue in the Base class and then just make sure each derived class implements their version of it.
If use of CRTP would work for you, you can use:
#include <string>
template <typename TypeSelector>
class Base {
public:
using type = typename TypeSelector::type;
virtual void getValue(type t) = 0;
};
struct TypeSelector_A {
using type = std::string&;
};
class Derived_A : public Base<TypeSelector_A> {
public:
void getValue(std::string& s) { /* Add real implementation */ }
};
struct TypeSelector_B {
using type = int*;
};
class Derived_B : public Base<TypeSelector_B> {
public:
void getValue(int* j) { /* Add real implementation */ }
};
int main()
{
Derived_A a;
Derived_B b;
}
But what I really want to do is something like this: Force each derived class to implement getValue() but each with a different signature
The whole point of having virtual function (abstract or not) is that you can use it with pointer or reference to the base class which means you would use signature of the function from the base class. With that having what you want is completely useless. What you want can be implemented by returning std::variant or std::any with every virtual function in tree so keeping signature the same.
You should think how would you use such concept if it would be possible. If you think somethink like this:
void foo( Base *b ) {
if( auto *d = dynamic_cast<Derived_A *>( b ) ) {
std::string str;
d->getValue( str );
...
}
if( auto *d = dynamic_cast<Derived_B *>( b ) ) {
int i = 0;
d->getValue( &i );
...
}
}
then getValue() does not need to be virtual, you only need vritual destrictor in Base. But this is considered bad design.

C++ add virtual method in polymorphic subclass

I have cumbersome class and I want to refactor it to replace type code with subclasses. At some point during such process I have following hierarchy:
// interface
ISomeClass(){
public:
virtual foo() = 0;
virtual ~ISomeClass();
}
// this class is cumbersome one with huge amount of conditional logic based on type
BaseSomeClass : public ISomeClass(){
public:
virtual foo(){
if(TYPE_0 == getType()){ // finally I want to move such conditional logic in subclass
doSmth();
} else if (TYPE_1 == getType()){
doAnother();
}
}
protected:
virtual int getType(){ // I temporary need it for refactoring issue
return type_; // to replace type_ with subclasses
}
private:
int type_;
};
// this classes is almost empty now, but I want to move there all conditional logic in future
class Implementation1 : public BaseSomeClass {
virtual int getType(){ // I temporary need it for refactoring issue
return TYPE_0; // to replace type_ with subclasses
}
};
class Implementation2 : public BaseSomeClass {
virtual int getType(){ // I temporary need it for refactoring issue
return TYPE_1; // to replace type_ with subclasses
}
};
In BaseSomeClassdefined additional virtual method getType(). Would this method behavior be polymorphic if I handle all the instances using some kind of interface ISomeClass pointer? Assuming the interface itself doesn't provide such virtual method. Please notice this code is a first step in refactoring, not final one. Also this is a simplified example and real code has tens of such methods, I need to do refactoring step by step. And the question is about C++ dynamic polymorphism.
You asked:
Would this method behavior be polymorphic if I handle all the instances using some kind of interface ISomeClass pointer? Assuming the interface itself doesn't provide such virtual method.
If the interface does not provide such a virtual method, you can't expect polymorphic behavior.
It'll be better to implement foo in Implementation1 and Implementation2.
class BaseSomeClass : public ISomeClass()
{
};
class Implementation1 : public BaseSomeClass
{
virtual void foo()
{
doSmth();
}
};
class Implementation2 : public BaseSomeClass
{
virtual void foo()
{
doAnother();
}
};
If you must use getType(), you can resort to template based polymorphic behavior.
template <typename D>
class BaseSomeClass : public ISomeClass()
{
public:
virtual foo()
{
int type = D::getType();
if(TYPE_0 == type)
{
doSmth();
}
else if (TYPE_1 == type)
{
doAnother();
}
}
};
Here, you are expecting D to provide the interface getType(). You might as well expect D to provide the interface foo.
template <typename D>
class BaseSomeClass : public ISomeClass()
{
public:
virtual void foo()
{
D::foo():
}
};

C++ Avoiding redefinition of code that needs to return a polymorphic type

I have a set of classes (SubClassA, SubClassB, etc) that inherit from SuperClass. These classes have a myriad of methods that are exactly identical between the subclasses, except that they return a reference to *this (a.k.a. SubClassX&). The return type can't be deprecated to SuperClass& either, because then the subclass-specific functions and members wouldn't be accessible.
I'm looking for a short, clean way to implement this so that I don't have to replicate the method code in each subclass.
The best thing I've been able to come up with is something like this (pseudo-code), but I'm not sure if this would even work:
//methods.cpp
SUBCLASS& general_method_1() {return *this;}
SUBCLASS& general_method_2() {return *this;}
And then:
#define SUBCLASS SubClassA
class SubClassA : public SuperClass
{
#include "methods.cpp"
SubClassA& specific_method_1() {return *this;}
}
#define SUBCLASS SubClassB
class SubClassB : public SuperClass
{
#include "methods.cpp"
SubClassB& specific_method_2() {return *this;}
}
Not to mention this seems kind of hackish and difficult to interpret. Any ideas?
EDIT:
I should have mentioned that I will need to be able to polymorphically access the subclasses through pointers to SuperClass. For example, the following needs to be valid:
SuperClass* subclass[2];
subclass[0] = new SubClassA;
subclass[1] = new SubClassB;
CRTP.
template <class Derived> class Base
{
Derived& derived() { return static_cast<Derived&>(*this); }
};
class Derived1: public Base<Derived1>
{
};
class Derived2: public Base<Derived2>
{
};
In order to access things polymorphically, one needs to split Base in two:
class Base
{
public:
virtual ~Base() {}
// virtual Base& derived() = 0; -- note: this will NOT work!
};
template <class Derived> class BaseImpl : public Base
{
Derived& derived() { return static_cast<Derived&>(*this); }
};
class Derived1: public BaseImpl<Derived1>
{
};
class Derived2: public BaseImpl<Derived2>
{
};
int main()
{
Base* b[2] = { new Derived1, new Derived2 };
}
The way I would do it:
class Dystopia {
using This = Dystopia;
This& beHappy() {
// make me happy
return *this;
}
};
class Utopia : public Dystopia {
using This = Utopia;
This& beHappy() {
return static_cast<This&>(Dystopia::beHappy());
}
};
The main point here is that when you are in a derived class you can explicitly call the base method.
Note that the typedef is just a commodity (is not required).
As a sidenode: avoid macros in C++. Can’t emphasise this enough: Avoid macros!!. Armageddon will come in macros and good luck then debugging the End of the world.
I am going to suggest the following:
Create a .h file that contains one or more macros to declare the common functions.
Create a .h file that contains one or more macros to define the common functions.
Add the include file created in (1) in the class header files and use the macro(s) to declare the functions.
Add the include file created in (2) in the class .cc files and the use the macro(s) to define the functions.
Example:
DeclareFunctionsMacros.h
#define DECLARE_FUNCTIONS(THIS_CLASS) \
THIS_CLASS& general_method_1(); \
THIS_CLASS& general_method_2();
DefineFunctionsMacros.h
#define DEFINE_FUNCTIONS(THIS_CLASS) \
THIS_CLASS& THIS_CLASS::general_method_1() { return *this; } \
THIS_CLASS& THIS_CLASS::general_method_2() { return *this; }
SubClassA.h
#include "DeclareFunctionsMacros.h"
class SubClassA : public SuperClass
{
DECLARE_FUNCTIONS(SubClassA);
SubClassA& specific_method_1() {return *this;}
}
SubClassA.cc
#include "DefineFunctionsMacros.h"
DEFINE_FUNCTIONS(SubClassA)
This will allow you to alter definitions of the macros used in defining the functions without needing to recompile everything that #includes SubClassA.h.
It's not clear from your question whether all you require is to make use of covariant return types and a template.
For example:
class SuperClass
{
public:
virtual SuperClass& method() = 0;
};
class SpecificA : public SuperClass
{
public:
int specificMethodA();
};
class SpecificB : public SuperClass
{
public:
int specificMethodB();
};
template<class Specific>
class SubClass : public Specific
{
public:
virtual SubClass& method() { return *this; }
};
int main()
{
SubClass<SpecificA> scA;
SubClass<SpecificB> scB;
scA.method().specificMethodA();
scB.method().specificMethodB();
}

wrapper to template class inherited by another class

template <class CollectionItem>
class Collection
{
void A();
// Many other utility functions
}
class ICollection
{
virtual void B() = 0;
}
class Base : public Collection<BaseItem>, public IBase
{
virtual void B();
}
Is there any way of offering Collection functions via ICollection interface without wrapping all the functions in Base class? ICollection : public Collection<CollectionItem> is not an option.
Bounty Update:
OK, so the original idea was to have Interface to all Collection classes. Before we continue, every CollectionItem also has Interface, let's call it ICollectionItem and ICollection only knows about ICollectionItem.
So what I did was create another template class as Interface to Collection template class - ICollection (pure virtual) accepting ICollectionItem(s). Collection class inherits this interface.
Every Collection class (inheriting Collection<CollectionItem> class) would also inherit it's Interface Collection class. That Interface then virtual inherits ICollection<ICollectionItem>. I'll just post the code :)
Here is the code:
template <class ICollectionItem>
class ICollection
{
public:
virtual const ICollectionItem* At(const int idx) = 0;
};
template <class CollectionItem, class ICollectionItem>
class Collection
: public ICollection,
public virtual ICollection<ICollectionItem> // Weak point
{
private:
List<CollectionItem*> fContainer;
public:
Collection(void) {}
virtual ~Collection() {}
virtual const ICollectionItem* At(const int idx); // Casting GetAt result
virtual const TCollectionItem& GetAt(const int idx) const
virtual ListIterator<TCollectionItem> >* GetIterator(void) const;
virtual ListIterator<ICollectionItem> >* Iterator(void) const; // Weak point
}
Example usage:
class IBaseItem
{
public:
virtual int Number() = 0;
{
class BaseItem
: public IBaseItem
{
public:
virtual int Number();
void SetNumber(int value);
}
class IBase
: public virtual ICollection<IBaseItem>
{
public:
virtual IBaseItem* ItemByName(String name) = 0;
virtual ~IBase() {}
}
class Base
: public Collection<BaseItem, IBaseItem>,
public IBase
{
public:
BaseItem* GetItemByName(String name);
virtual IBaseItem* ItemByName(String name);
}
Weak points:
First is at using virtual inheritance ... lots written about it, not much to talk about, or is it?
Unable to access Iterator using ICollection interface. See ListIterator function, only first one can be implemented, the second one would require some kind of new List of IBaseItem. I decided to live with that and just use for loop.
Even tho I somehow managed to get what I wanted (With wrapping and casting), I would still like to hear an second opinion. I don't like using virtual inheritance, specially in such delicate situations - using Collections for application Base creation.
I can not see any other solution than calling some Collection method in Base implementation of IBase virtual methods.
class Base : public Collection<BaseItem>, public IBase
{
virtual void B()
{
A();
}
}
You say, and I quote:
I want to call Collection functions using IBase pointer
I really don't see what is to be done here besides dynamic_cast. It does exactly what you want it to do.
void fun(IBase * base) {
auto * coll = dynamic_cast<Collection<BaseItem>*>(base);
if (coll) {
coll->A();
}
}
Your Collection class must have a virtual destructor.
You can, of course, offer a templated version, if you'd need different baseitems in different, scenarios for some reasons. This has bad code smell and I think your architecture is bad at this point, but oh well.
template <typename T> void fun(IBase * base) {
auto * coll = dynamic_cast<Collection<T>*>(base);
if (coll) {
coll->A();
}
}
void test(IBase * p) {
fun<BaseItem5>(p);
}
If you have some other specific scenario in mind, please edit your question to say what you mean.
Hmm...So you wanna to reuse the Collection class's utility functions, and you want to design a class which will implement an interface defined by IBase. As you mentioned above,"wrapping all the functions in Base class" is a way to offer Collection functions.
(1) Via inheritance,derived class has a good knowledge of Collection
class Derived:public Collection<DerivedType>,public IBase{};
or
template <typename T>
class Derived:public Collection<T>,public IBase{};
(2) Via inheritance,derived class knows little about Collection,but through IBase
class IBase : public Collection<BaseItem>{};
class Derived:public IBase{};
By (1),If you want to call Collection functions using IBase pointer,you have to wrap the functions.
By (2), any Derived instance is " a kind of " IBase which is "a kind of " Collection. So you can use IBase pointer to call Collection functions.
So,the key point is that the objects pointed by the IBase pointer should have the method you want to call.Wrap it or inherit it. I can not see any other solution than these two ways.
Edit: the idea is refined based on your example:
Here is an idea:
//generic interface can be kept as it is
template <class ICollectionItem>
class ICollection
{
public:
virtual const ICollectionItem* At(const int idx) = 0;
};
class Empty
{
};
template <class CollectionItem , class BaseClass = Empty>
class GenericCollection
: public BaseClass
{
public:
const CollectionItem* At(const int idx);
// At and ItemByName are standard functions for a collection
CollectionItem* ItemByName(String name);
//note that here nothing has to be declared as virtual
};
//example usage:
class IBase
: public virtual ICollection<IBaseItem>
{
public:
virtual IBaseItem* ItemByName(String name) = 0;
virtual ~IBase() {}
};
class Base
: public GenericCollection<BaseItem, IBase >
{
public:
//nothing to be implemented here, all functions are implemented in GenericCollection and defined as virtual in IBase
//The definition of the functions has to be the same:
};
In collection you can implement whatever and in the interface you can define what ever you want to be virtual from your collection. The only thing is that you need to have some standard in naming convention for functions.
Hope this helps,
Raxvan.
From your comments in another answer, it seems you want a collection of interfaces, and an implementation of this interface. The simplest I can advise you is the following:
template<typename T>
class ICollection
{
public:
virtual iterator<T>* begin() const = 0;
};
template<typename T, typename TBase>
class Collection : public ICollection<TBase>
{
public:
iterator_impl<T>* begin() const { return whatever; }
};
Example:
class IItem {};
class Item : public IItem {};
class Base : public Collection<Item, IItem> {};
old answer:
Is there any way of offering Collection functions via IBase interface without wrapping all the functions in Base class ?
If I understood your problem, you want to use it like this:
void myfunc()
{
// ...
IBase* obj = ...;
obj->A();
obj->B();
}
I think here is a misunderstanding here: if you want A() to be callable from an IBase, then you have to add it to Ibase declaration.
If you want to use the Collection functions on an object, then you should cast this object to a Collection, via dynamic_cast for example.
Furthermore, if you have such a funcion:
void fun(IBase* base) { /* ... */ }
you cannot cast to a Collection*, since there are no relationship between these two classes, unless you have another way to be sure base is a Collection:
void fun(IBase* base)
{
if(base && base->isABaseItemCollection())
{
// Valid, since the real type was checked before
Collection* collection = (Collection*)base;
// ...
}
}
On a side note: you can generate bases almost automatically:
template
class Base : public Collection, public U {};
typedef Base BaseCollection;
According to comment/chat:
You have something like:
class IAnimal { /*...*/ };
class Cat : public IAnimal { /*...*/ };
class Dog : public IAnimal { /*...*/ };
class Cats
{
std::vector<Cat*> cats;
public:
Cat* at(size_t index) { return cats[index]; }
/*...*/
};
class Dogs
{
std::vector<Dog*> dogs;
public:
Dog* at(size_t index) { return dogs[index]; }
/*...*/
};
And you want to factorize some code using something like
class IAnimals
{
public:
std::vector<IAnimals*> animals; // or getter/setter which works with IAnimals.
/* some common factorized code */
};
// And so
class Cats : public IAnimals { /**/ };
class Dogs : public IAnimals { /**/ };
I propose, instead of creating class IAnimals, to use template functions as:
template <typename TAnimals>
void foo(TAnimals& animals)
{
Ianimals* animal = animals.at(42);
// ...
animal->eat(food);
// ...
}
You have to give compatible "interface" (names) to the type used in template.
Maybe you could have an operator() in IBase that would be delegated to Base?
class CollectionBase {};
template <class Item> class Collection: public CollectionBase {};
class IBase
{
public:
virtual CollectionBase* operator()() = 0;
};
class Base : public Collection<BaseItem>, public IBase
{
public:
virtual Collection<BaseItem>* operator()() { return this; }
};

Multiple inheritance hierarchy

I'm looking for a clean way of doing this since a long time. In my problem, there exist 3 classes not sharing any parent in common but each having some methods with the same name (A.doSomething, B.doSomething, C.doSomething). Hence, having the same function signature, class D inheriting from A and using method doSomething() will "look the same" to E inheriting from B or C .
Here is a sketch of what I'd like to be able to do:
class Base {
public:
void myMethod(void) { doSomething(); }
};
class Independent {
public:
doSomething();
};
clase Derived : public Base : public Independent {
(...)
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}
In this problem, object of type "Independent" is provided by a library that I cannot change. I would like to define a base class that uses methods that are going to be inherited later on. I couldn't find a proper way of doing this using virtual inheritance without causing ambiguous compiling.
You've got a nasty situation there. One solution to this would be using the Curiously Recurring Template Pattern to perform the inheritance at compile-time, like this:
template <typename D>
class Base {
public:
void myMethod(void) { static_cast<D*>(this)->doSomething(); }
};
class Independent {
public:
void doSomething();
};
clase Derived : public Base : public Independent {
/*...*/
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}
Alternatively, you could choose to put a middleman class in between to forward to Independent (I assume you have many classes deriving from the same Base and Independent, and just don't want to have to do this for each class).
template <typename D>
class Base {
private:
virtual void doSomethingImpl();
public:
void myMethod(void) { doSomethingImpl(); }
};
class Independent {
public:
void doSomething();
};
class IndependentWrapper : public Base : public Independent {
private:
void doSomethingImpl() { Independent::doSomething(); }
};
clase Derived : public IndependentWrapper {
/*...*/
};
int main(void) {
Derived *derivedObject = new Derived();
derivedObject->myMethod();
}