C++ Cloneable mixin - c++

I have several classes that need the following clone function to be defined:
struct Base
{
virtual Base * clone() const = 0;
};
struct A : public Base
{
Base * clone() const {
return new A(*this);
}
};
struct B : public Base
{
Base * clone() const {
return new B(*this);
}
};
struct X : public Base2
{
Base2 * clone() const {
return new X(*this);
}
};
I am trying to do this with a Cloneable mixin to avoid this redundant code:
template <typename BASE, typename TYPE>
class CloneableMixin
{
public:
BASE*clone() const {
return new TYPE( dynamic_cast<const TYPE &>(*this) );
}
};
struct A : public Base, public CloneableMixin<Base, A>
{
};
However, this doesn't work, because in new TYPE(*this) from CloneableMixin, *this is of type CloneableMixin<BASE, TYPE>.
Update: the CloneableMixin can dynamic_cast to the correct type. But now I have another problem: CloneableMixin::clone doesn't successfully override Base::clone, and so the compiler reports A is a abstract type.
Can some clever use of virtual inheritance allow CloneableMixin::clone to override Base::clone? Is there some macro I should use for this?
Do you know of a way around all of this redundant code?

Can some clever use of virtual inheritance allow CloneableMixin::clone to override Base::clone?
Your CloneableMixin<Base,Derived> cannot override any method of Base - either
polymorphically or by hiding - because CloneableMixin<Base,Derived> is
not derived from Base.
On the other hand, if CloneableMixin<Base,Derived> were derived from Base
you would no longer have any need for it to be a mixin, because -
class Derived : public CloneableMixin<Base,Derived> {....};
would inherit Base.
So for the needs of your example the solution illustrated here will suffice:
#include <iostream>
// cloner v1.0
template <class Base, class Derived>
struct cloner : Base
{
Base *clone() const override {
return new Derived( dynamic_cast<const Derived &>(*this) );
}
~cloner() override {};
};
struct Base
{
virtual Base * clone() const = 0;
Base() {
std::cout << "Base()" << std::endl;
}
virtual ~Base() {
std::cout << "~Base()" << std::endl;
}
};
struct A : cloner<Base,A>
{
A() {
std::cout << "A()" << std::endl;
}
~A() override {
std::cout << "~A()" << std::endl;
}
};
int main()
{
A a;
Base * pb = a.clone();
delete pb;
}
(If you are compiling to the C++03 standard rather than C++11, then you may
simply delete the occurrences of the override keyword.)
This solution will break down for some more real-worldly class hierarchies,
e.g. in this illustration of the Template Method Pattern:
#include <iostream>
#include <memory>
using namespace std;
// cloner v1.0
template<class B, class D>
struct cloner : B
{
B *clone() const override {
return new D(dynamic_cast<D const&>(*this));
}
~cloner() override {}
};
/* Abstract base class `abstract` keeps the state for all derivatives
and has some pure virtual methods. It has some non-default
constructors.
*/
struct abstract
{
virtual ~abstract() {
cout << "~abstract()" << endl;
}
int get_state() const {
return _state;
}
void run() {
cout << "abstract::run()" << endl;
a_root_method();
another_root_method();
}
virtual void a_root_method() = 0;
virtual void another_root_method() = 0;
virtual abstract * clone() const = 0;
protected:
abstract()
: _state(0) {
cout << "abstract(): state = " << get_state() << endl;
}
explicit abstract(int state) : _state(state) {
cout << "abstract(" << state << ") : state = "
<< get_state() << endl;
}
int _state;
};
/* Concrete class `concrete` inherits `abstract`
and implements the pure virtual methods.
It echoes the constructors of `abstract`. Since `concrete`
is concrete, it requires cloneability.
*/
struct concrete : cloner<abstract,concrete>
{
concrete() {
cout << "concrete(): state = " << get_state() << endl;
}
explicit concrete(int state) : abstract(state) { //<- Barf!
cout << "concrete(" << state << ") : state = "
<< get_state() << endl;
}
~concrete() override {
cout << "~concrete()" << endl;
}
void a_root_method() override {
++_state;
cout << "concrete::a_root_method() : state = "
<< get_state() << endl;
}
void another_root_method() override {
--_state;
cout << "concrete::another_root_method() : state = "
<< get_state() << endl;
}
};
int main(int argc, char **argv)
{
concrete c1;
unique_ptr<abstract> pr(new concrete(c1));
pr->a_root_method();
pr->another_root_method();
unique_ptr<abstract> pr1(pr->clone());
pr1->a_root_method();
return 0;
}
When we attempt to build this, the compiler will give an error at
the initialization abstract(state) in the constuctor of concrete (at the Barf!
comment), saying:
error: type 'abstract' is not a direct or virtual base of 'concrete'
or words to that effect. Indeed, the direct base of concrete is not abstract
but cloner<abstract,concrete>. However, we cannot rewrite the constructor as:
/*Plan B*/ explicit concrete(int state) : cloner<abstract,concrete>(state){....}
Because there is has no such constructor as
cloner<abstract,concrete>::cloner<abstract,concrete>(int)
But the compiler's diagnostic suggests a fix. This is were virtual
inheritance can help. We need abstract to become a virtual base of concrete, which
means effectively "an honorary direct base of concrete", and we can achieve that
just by making B a virtual base of cloner<B,D>:
// cloner v1.1
template<class B, class D>
struct cloner : virtual B
{
B *clone() const override {
return new D(dynamic_cast<D const&>(*this));
}
~cloner() override {}
};
With that, we have a clean build and output:
abstract(): state = 0
concrete(): state = 0
concrete::a_root_method() : state = 1
concrete::another_root_method() : state = 0
concrete::a_root_method() : state = 1
~concrete()
~abstract()
~concrete()
~abstract()
~concrete()
~abstract()
There are good reasons to be wary of virtual inheritance on principle
and to reserve its use for at least for cases in which it has architectural
rationale - not for workarounds, as we have used it just now.
If we prefer to do without virtual inheritance for this problem, then we
must somehow ensure that there is a constructor of cloner<B,D> that
echoes any constuctor of B, for arbitrary B. Then any corresponding
constructor of D will be able to initialize its direct base cloner<B,D>
whatever the arguments are.
This is a pipedream for C++03, but with the magic of variadic template
parameters in C++11 it is easy:
// cloner v1.2
template<class B, class D>
struct cloner : B
{
B *clone() const override {
return new D(dynamic_cast<D const&>(*this));
}
~cloner() override {}
// "All purpose constructor"
template<typename... Args>
explicit cloner(Args... args)
: B(args...){}
};
With this, we can rewrite the concrete constructor as /*Plan B*/, and
again we have a correct build and executable.

During the instantiation of your Cloneable mixin, the derived class is still in an incomplete type. You could try to add the proverbial extra leval of indirection like this:
template
<
typename Derived
>
class Cloneable
:
private CloneableBase
{
public:
Derived* clone() const
{
return static_cast<Derived*>(this->do_clone());
}
private:
virtual Cloneable* do_clone() const
{
return new Derived(static_cast<const Derived&>(*this));
}
};
class CloneableBase
{
public:
CloneableBase* clone() const
{
return do_clone();
}
private:
virtual CloneableBase* do_clone() const=0;
};
class MyClass: public Cloneable<MyClass>;

Related

How to hide param type of template base class

Not sure if this is even possible but here goes...
I'm trying to hide the param of a template base class by doing the following:
Expose a common interface
Implement template base class that implements the common interface
Implement several concrete derived classes
Use a factory class to instantiate the concrete derived classes
So far so good, but the problem is the return type of my factory class is IBase so the default implementation of foo is called instead of DerivedA or DerivedB :(
Anyway for this approach to work? or back to the drawing board?
// Common interface
class IBase {
public:
virtual std::string foo() { return "IBase"; };
}
// Template base class
template <typename T>
class Base : public IBase {
public:
Base(T value) : m_precious(value) {}
virtual ~Base() {}
protected:
T m_precious;
}
// Concrete derived classes
class DerivedA : public Base<int> {
public:
DerivedA(int value) : Base<int>(value) {}
virtual std::string foo() override {
return "DerivedA";
};
}
class DerivedB : public Base<float> {
public:
DerivedB(float value) : Base<float>(value) {}
virtual std::string foo() override {
return "DerivedB";
};
}
// Factory interface
class Factory {
public:
template<typename T>
static IBase create(T value);
};
template<>
IBase Factory::create<int>(int value) {
return DerivedA(value);
}
template<>
IBase Factory::create<float>(float value) {
return DerivedB(value);
}
// Caller
int main() {
int valueA = 3;
float valueB = 3.14;
// This is how I want to use the API
IBase A = Factory::create(valueA);
IBase B = Factory::create(valueB);
std::cout << A.foo() << std::endl;
std::cout << B.foo() << std::endl;
}
The above code prints:
IBase
IBase
But I want this:
DerivedA
DerivedB
You currently have object slicing, your code should be something like:
// Factory interface
class Factory {
public:
template<typename T>
static std::unique_ptr<IBase> create(T value);
};
template<>
std::unique_ptr<IBase> Factory::create<int>(int value) {
return std::make_unique<DerivedA>(value);
}
template<>
std::unique_ptr<IBase> Factory::create<float>(float value) {
return std::make_unique<DerivedB>(value);
}
With usage:
auto A = Factory::create(valueA);
auto B = Factory::create(valueB);
std::cout << A->foo() << std::endl;
std::cout << B->foo() << std::endl;

Using visitor pattern for checking derived class type?

I am using the visitor pattern to deal with a lot of different AST problems, which turns out to work really well. For instance, I am using it to check for static type. This works well when looking for the exact type, however it doesn't apply to derived classes. i.e. If we have Derived that inherit from Base, asking if a Derived object is a Base fails.
Consider the following C++ code:
#include <iostream>
#include <functional>
#include <memory>
using namespace std;
class Base;
class Derived;
class Visitor {
public:
virtual void visit(Base& object) = 0;
virtual void visit(Derived& object) = 0;
};
class EmptyVisitor : public Visitor {
public:
virtual void visit(Base& object) override {}
virtual void visit(Derived& object) override {}
};
template <class TYPE> class LogicVisitor : public EmptyVisitor {
public:
LogicVisitor(function<void(TYPE&)> logic) : EmptyVisitor(), logic(logic) {}
virtual void visit(TYPE& object) override { logic(object); }
private:
function<void(TYPE&)> logic;
};
class Base {
public:
virtual void accept(Visitor* visitor) {
visitor->visit(*this);
}
};
class Derived : public Base {
public:
virtual void accept(Visitor* visitor) override {
visitor->visit(*this);
}
};
template <class TYPE> bool is_type(shared_ptr<Base> base)
{
bool is_type = false;
LogicVisitor<TYPE> logic_visitor([&](TYPE& object) {
is_type = true;
});
base->accept((Visitor*)&logic_visitor);
return is_type;
}
int main() {
auto base = make_shared<Base>();
auto derived = make_shared<Derived>();
cout << "is_type<Base>(base) = " << (is_type<Base>(base) ? "true" : "false") << endl;
cout << "is_type<Derived>(base) = " << (is_type<Derived>(base) ? "true" : "false") << endl;
cout << "is_type<Base>(derived) = " << (is_type<Base>(derived) ? "true" : "false") << endl;
cout << "is_type<Derived>(derived) = " << (is_type<Derived>(derived) ? "true" : "false") << endl;
return 0;
}
It outputs as expected the following result:
is_type<Base>(base) = true
is_type<Derived>(base) = false
is_type<Base>(derived) = false
is_type<Derived>(derived) = true
While this is great to retrieve the static type of an object, how can this be fixed if I wanted is_type<Base>(derived) to return true instead of false so that I can effectively check class inheritance? Is this possible in C++?
You cannot. The reason why is overload resolution (and your design pattern). Every visitor has two overloads, one for Base& and the second one for Derived&. LogicVisitor overrides the function with the type passed as template parameter, so for Base it will override void visit(Base&).
You want it to override void visit(Derived&) for Base instead (or additionally). But that would require the visitor to find every class that derives from Base, which is not possible at the moment.
You can use std::is_base_of instead:
template<typename T, typename U>
constexpr bool is_type(std::shared_ptr<U>) {
return std::is_base_of_v<std::decay_t<T>, std::decay_t<U>>;
}

Adding invariants in non virtual interface idiom

Suppose I have the following hierarchy using the NVI idiom :
class Base
{
public:
virtual ~Base() {}
void foo() { cout << "Base::foo" << endl; foo_impl(); }
private:
virtual void foo_impl() = 0;
};
class A : public Base
{
private:
virtual void foo_impl() { cout << "A::foo_impl" << endl; }
};
If at some point in the hierarchy I want to "add" invariants in the non virtual base method, what would be the best way to do so ?
One way would be to recurse the NVI idiom at the SpecialBase level :
class SpecialBase : public Base
{
private:
void foo_impl() { cout << "SpecialBase::foo" << endl; bar_impl(); }
virtual void bar_impl() = 0;
};
class B : public SpecialBase
{
private:
virtual void bar_impl() { cout << "B::bar_impl" << endl; }
};
But I don't really like this idea, since I don't want to add methods (with different names) for each derived bases I add to my hierarchy...
Another way is to have the following (which is not NVI) :
class Base
{
public:
virtual ~Base() {}
virtual void foo() { base_foo(); foo_impl(); }
protected:
void base_foo() { cout << "Base::foo" << endl; }
virtual void foo_impl() = 0;
};
class SpecialBase : public Base
{
public:
virtual void foo() { base_foo(); specialbase_foo(); foo_impl(); }
protected:
void specialbase_foo() { cout << "SpecialBase::foo" << endl; }
};
class B : public SpecialBase
{
private:
virtual void foo_impl() { cout << "B::foo_impl" << endl; }
};
Which in my opinion is less confusing since at any point a concrete class just has to implement the virtual method, while a derived base class can override the base (virtual) method if it chooses too.
Is there another cleaner way to achieve the same ?
EDIT:
I'm looking for a very general design pattern that could allow me to have the following kind of hierarchy :
Base <- A
<- B
<- SpecialBase <- C
<- D
<- VerySpecialBase <- E
<- StrangeBase <- F
Where each Base class can (and will override foo), whereas classes A-F will only need to reimplement foo_impl.
Note that just adding another optional customization virtual function (e.g bar_impl) won't help here, because it only allow for one extra layer of customization, where I could possibly need an infinite number.
In my understanding, NVI is a way to prevent/discourage adding invariants to the non-virtual base method, so the fact that you want to add invariants at this point suggests that NVI either isn't the pattern you are looking for at all, or you might want to restructure your design so that you do not need to add such invariants.
That being said an alternative to simply making your previously non-virtual interface virtual would be to employ the final keyword from C++11:
class Base
{
public:
virtual ~Base() {}
virtual void foo() { base_foo(); foo_impl(); }
protected:
void base_foo() { cout << "Base::foo" << endl; }
virtual void foo_impl() = 0;
};
class SpecialBase : public Base
{
public:
virtual void foo() final // note the use of 'final'
{ base_foo(); specialbase_foo(); foo_impl(); }
protected:
void specialbase_foo() { cout << "SpecialBase::foo" << endl; }
};
class B : public SpecialBase
{
private:
virtual void foo_impl() { cout << "B::foo_impl" << endl; }
};
Here NVI is not implemented by the class Base, but is implemented at the level of SpecialBase since classes derived from SpecialBase can no longer override the public interface (namely foo).
In this way we are saying that the public interface of Base is allowed to be overridden (invariants may be added, or even the entire function may be reimplemented), but the public interface of SpecialBase is not.
Personally I find that this can be useful in some limited cases, but most of the time I simply wanted a more complete interface in Base in the first place.
Ultimately I think it is more common to use Base to clearly define what points of customization are allowed:
class Base
{
public:
virtual ~Base() {}
virtual void foo() { base_foo(); bar_impl(); foo_impl(); }
protected:
void base_foo() { cout << "Base::foo" << endl; }
virtual void bar_impl() {} // bar_impl is an optional point of customization
// by default it does nothing
virtual void foo_impl() = 0; // foo_impl is not optional derived classes
// must implement foo_impl or else they will be abstract
};
class B : public Base
{
private:
virtual void bar_impl() { cout << "SpecialBase::foo" << endl; }
virtual void foo_impl() { cout << "B::foo_impl" << endl; }
};
Note that there is no longer a need for the SpecialBase class layer at all.
This post was suggested to me as similar to something I was browsing related to NVI the other day, hence the necro.
I would suggest adding a Check-Adding mechanism in the base class, so that derived classes can add requirements. This works in a very straightforward way as long as the requirements can be tested using the base class access functions, otherwise your special MyInvariant class has to dynamic_cast the base argument of doCheckInvariantOK() for the invariant to work.
edit: I understand 'invariant' to be along the lines of pre- and post-conditions of foo(), as in formal verfication. If you want to add functionality before and/or after base_foo(), what I think you're actually after, you can do it in an analogous fashion.
class Base
{
public:
virtual ~Base() {}
void foo()
{
cout << "Base::foo" << endl;
//Can use invariants as pre and/or postconditions for foo_impl
for(const std::unique_ptr<InvariantBase>& pInvariant : m_invariants)
{
//TODO cout << "Checking precondition " << pInvariant->GetDescription() << endl;
if(!pInvariant->CheckInvariantOK(*this))
{
//Error handling
}
}
foo_impl();
}
protected:
void AddInvariant(std::unique_ptr<InvariantBase>&& pInvariant)
{
m_invariants.push_back(std::move(pInvariant));
}
struct InvariantBase
{
bool CheckInvariantOK(const Base& base)
{
return doCheckInvariantOK(base);
}
private:
virtual bool doCheckInvariantOK(const Base& base) = 0;
};
private:
std::list<std::unique_ptr<InvariantBase>> m_invariants;
virtual void foo_impl() = 0;
};
class A : public Base
{
private:
virtual void foo_impl() { cout << "A::foo_impl" << endl; }
};
class SpecialBase : public Base
{
public:
SpecialBase()
: Base()
{
AddInvariant(std::unique_ptr<MyInvariant>(new MyInvariant() ) );
}
private:
void foo_impl() { cout << "SpecialBase::foo" << endl; bar_impl(); }
virtual void bar_impl() = 0;
struct MyInvariant : public InvariantBase
{
virtual bool doCheckInvariantOK(const Base& base) override
{
//TODO: special invariant code
}
};
};
class B : public SpecialBase
{
private:
virtual void bar_impl() { cout << "B::bar_impl" << endl; }
};

C++ virtual functions base return type suggestions

I need a base class that gives me primitive type of data's pointer. I add a function in it. I derived types of class. I used void * to support all primitive types as a return type but it is like old C days. It is not good for OOP. Does one have an suggestion to do in a proper way in OOP?
#include <iostream>
class base {
public:
virtual void *getPtr() = 0;
virtual ~base() {};
};
class derivedAType : public base {
protected:
int _i;
public:
derivedAType(int i): _i(0) { _i = i; };
virtual ~derivedAType() {}
virtual void *getPtr() {
return static_cast<void *>(&_i);
}
};
class derivedBType : public base {
protected:
short _s;
public:
derivedBType(short s): _s(0) { _s = s; };
virtual ~derivedBType() {}
virtual void *getPtr() {
return static_cast<void *>(&_s);
}
};
int main()
{
base *b1 = new derivedAType(1203912);
base *b2 = new derivedBType(25273);
std::cout << "b1 : " << *(static_cast<int *>(b1->getPtr()))
<< "\nb2 : " << *(static_cast<short *>(b2->getPtr()))
<< std::endl;
delete b2;
delete b1;
return 0;
}
Make the base class a template class with the data type as the template variable
template<typename DataType>
class base {
virtual DataType* getPtr() = 0;
//...
};
and
class derivedAType : public base<int>
But this changes base class to a template class which means you cant store them together, base<int> is different from base<short>
If this isnt acceptable, the other options is just a tad bit cleaner than your code but abt the same, refer to this question. Basically derived class return types can reflect their true type and i think it should get automatically converted to void*, so you dont have to manually cast the pointer.
Not sure about your problem. But maybe a double callback can help:
class Callback {
public:
virtual void do_int( int i ) const = 0;
virtual void do_short( short s ) const = 0;
/* ... */
}
class base {
public:
virtual void do_stuff(const Callback & c); /* will need a more telling name */
virtual ~base() {};
};
class derivedAType : public base {
protected:
int _i;
public:
derivedAType(int i): _i(0) { _i = i; };
virtual ~derivedAType() {}
virtual void do_stuff(const Callback & c) {
c.do_int( _i );
}
};
class derivedBType : public base {
protected:
short _s;
public:
derivedBType(short s): _s(0) { _s = s; };
virtual ~derivedBType() {}
virtual void do_stuff( const Callback & c) {
c.do_short( _s );
}
};
class print_callback : public Callback {
public:
virtual void do_int( int i ) const { std::cout << i; }
virtual void do_short( short s ) const { std::cout << s; }
}
int main() {
base *b1 = new derivedAType(1203912);
base *b2 = new derivedBType(25273);
std::cout << "b1 : ";
b1->do_stuff(print_callback());
std::cout << "\nb2 : ";
b2->do_stuff(print_callback());
std::cout << std::endl;
delete b2;
delete b1;
return 0;
}
Of course you can simplify this by just storing the created print callback, and using it twice.

Is it possible to adapt the "Prototype pattern" to rvalue references?

I have a hierarchie of classes that implement the Prototype pattern and I would like to use move semantics to limit objects deep copy. I tried to adapted the pattern with a move() member function which meaning is that I do not need the original object anymore. Here is what I have so far:
#include <iostream>
#include <utility>
#include <vector>
struct base
{
virtual ~base() { }
virtual base* clone() const = 0;
virtual base* move() = 0;
};
struct derived1 : public base
{
derived1() { std::cout << "derived1::derived1()\n"; }
derived1(const derived1&) { std::cout << "derived1::derived1(const derived1&)\n"; }
derived1(derived1&&) { std::cout << "derived1::derived1(derived1&&)\n"; }
virtual ~derived1() { }
virtual base* clone() const { return new derived1(*this); }
virtual base* move() { return new derived1(std::move(*this)); }
};
struct derived2 : public base
{
derived2() { std::cout << "derived2::derived2()\n"; }
derived2(const derived2&) { std::cout << "derived2::derived2(const derived2&)\n"; }
derived2(derived2&&) { std::cout << "derived2::derived2(derived2&&)\n"; }
virtual ~derived2() { }
virtual base* clone() const { return new derived2(*this); }
virtual base* move() { return new derived2(std::move(*this)); }
};
std::vector<base*> vec;
void foo(const base& obj)
{
vec.push_back(obj.clone());
}
void foo(base&& obj)
{
vec.push_back(obj.move());
}
int main()
{
derived1 d1;
derived2 d2;
foo(d1);
foo(d2);
foo(derived1());
foo(derived2());
}
When I run it, it show that the good constructors are used:
derived1::derived1()
derived2::derived2()
derived1::derived1(const derived1&)
derived2::derived2(const derived2&)
derived1::derived1()
derived1::derived1(derived1&&)
derived2::derived2()
derived2::derived2(derived2&&)
So far, it seems good. I am just not sure if this is a standard compliant usage of the rvalue references. Is there a point I did not think of that would produce undesirable results?
For recurring method definition I prefer CRTP. For your case I'd declare something like:
template<typename TDerived>
class virtually_clonable : public base
{
public:
virtual base* clone() override
{
return new TDerived(*AsDerived());
}
virtual base* move() override
{
return new TDerived(std::move(*AsDerived()));
}
private:
TDerived* AsDerived()
{
return static_cast<TDerived*>(this);
}
};
And while implementing the classes:
class derived1 : public virtually_clonable<derived1>
{
public:
/* your ctors goes here*/
/* no need to implement clone/move again */
};
class derived2 : public virtually_clonable<derived2>
{
public:
/* your ctors goes here*/
/* no need to implement clone/move again */
};
By the way you may want to return shared_ptr objects instead of raw pointers. That is usually the case for clonable types instead of unique_ptr.