C++ SafeSingleton 3 level inheritance - c++

I have a templated SafeSingleton class, Base class which is derived from SafeSingleton and implements some base methods. I want to have class that is derived from Base and can be accessed via instance() method of SafeSingleton. The problem is that when I am trying to access Derived::instance() it returns the pointer to a Base class and the compiler doesn't know anything about methods of derived class. What should I do to make below code work.
template<class T>
class SingleTon {
public:
static T* instance()
{
return holder().instance;
}
protected:
template<class I>
struct Holder
{
Holder() : instance(new I())
{
}
I* instance;
};
static Holder<T> &holder()
{
static Holder<T> holder;
return holder;
}
};
// Hopefully issue is here, I am never creating SingleTon<Derived>, but how can it be done?
class Base : public SingleTon<Base> {
public:
Base() = default;
void printBase() {
std::cout << "Base";
}
};
class Derived : public Base {
public:
Derived() = default;
void printDerived() {
std::cout << "Derived";
}
};
int main()
{
Derived::instance()->printBase();
Derived::instance()->printDerived(); // Here is the error
//Error: main.cpp:57:26: error: ‘class Base’ has no member named ‘printDerived’
//57 | Derived::instance()->printDerived();
return 0;
}

template<class D>
class Base : public SingleTon<D> {
and
class Derived : public Base <Derived>
and ... done?
If you want to put Base's non-Ddependent methods in a cpp file, you'll have to get fancy. Have BaseImp that does not derive from SingleTon, put code there. Have Base<D> derive from it and write forwarding glue to it BaseImpl. But you probably don't need this.

Related

Can a base class be declared in C++ such that classes derived from it can only be created via a creation function?

in something like the following
class Base
{
protected:
Base()
{}
public:
virtual void initialize()
{}
template<typename D, typename... Ts>
static std::shared_ptr<D> create(Ts... args)
{
auto d = std::shared_ptr<D>(new D(args...));
d->initialize();
return d;
}
};
class Derived : public Base
{
private:
int value_;
protected:
public:
Derived(int v) : value_(v)
{}
void initialize() override
{
//Do something with value_
}
};
int main()
{
auto derived = Base::create<Derived>(42);
// etc.
return 0;
}
The above works as expected but if Base was part of a class library that the user of the library was extending by implementing Derived, there is nothing preventing the user of the library from creating a Derived via its public constructor and thus initialize won't be called.
In such a library/library user scenario how could one enforce usage of something like Base::create(...) for Derived class creation?
For example, if Base::Base() is made private rather than protected the code won't compile because Derived::Derived() wont be able to access it.
This solution is a bit finicky, but I think it covers all bases:
class Base
{
protected:
// Token is only visible to Derived, and only constructible by Base
class token {
friend Base;
token() {};
};
// Constructing Base requires a token
Base(token)
{}
public:
// bla
template<typename D, typename... Ts>
static std::shared_ptr<D> create(Ts... args)
{
auto d = std::shared_ptr<D>(new D({}, args...));
// Token is created here ^^
// bla
}
};
class Derived : public Base
{
// bla
public:
// Derived receives and forwards the token to Base
// The implicit copy constructor is accessible
Derived(token t, int v) : Base(t), value_(v)
{}
// bla
};
Thus, no one can write Derived d(Base::token{}, 42) because token is inaccessible. Derived itself can name token and pass one around, but cannot create one: only Base's create function can.
If your aim is just to make sure that initialize function is called by derived classes make it pure virtual.
I would suggest to use Non-Virtual Interface(NVI) idiom.
In this way library users are enforced to implement doInitialize function in derived classes.
class Base
{
protected:
Base()
{
}
public:
void initialize()
{
doInitialize();
}
template<typename D, typename... Ts>
static std::shared_ptr<D> create(Ts... args)
{
auto d = std::shared_ptr<D>(new D(args...));
d->initialize();
return d;
}
virtual ~Base() = default;
protected:
virtual void doInitialize() = 0;
};
class Derived : public Base
{
private:
int value_;
public:
Derived(int v) : value_(v)
{}
private:
void doInitialize() override
{
//Do something with value_
}
};
int main()
{
auto derived = Base::create<Derived>(42);
return 0;
}

Calling the right free function from a base pointer/reference

Let a class hierarchy :
class Base { virtual ~Base() throw(); };
class DerivedA : public Base { };
class DerivedB : public Base { };
I would like to have some code specific to each of these derived classes. However that code also being specific to the application that makes use of this class hierarchy, I do not want to embbed this derived-class-specific code into these derived classes. To avoid doing so, I thought about writing free functions :
void DerivedASpecificWork( DerivedA da );
void DerivedBSpecificWork( DerivedB db );
However, when given an instance of a derived class through a reference/pointer to a Base, I do not have access to the actual type of the instance, and thus cannot call the proper Derived*SpecificWork() function.
I would like to know if there is nome kind of design pattern that would allow me to call a derived-class-specific function without knowing the actual type of the instance, i.e having the same mechanism as virtual functions provide, but without having these virtual functions that would require me to embbed application-specific code into that class hierarchy.
Actually, why I want to do that is to provide informations about an exception that occured within a natively implemented function called by a Lua script. Each exception carrying its own set of information, the way I want to represent the error within the script depends on the type of the exception. I could create a pure virtual method in the base class that would be implemented by derived classes, but this would require me to embbed Lua-related code into my exception hierarchy, which I do not want to do since the Lua is specific to one of the application using that exception hierarchy.
Also I cannot use C++11.
Thank you.
May be Brigde pattern can help you.
This pattern can be used when you want to avoid a permanent binding between an abstraction and it's implementation.
(I don't see your comment about your restriction in using c++11, but you can remove std::unique_ptr, std::move and override keyword)
class AppSpecificImp
{
public:
virtual void DoWork() = 0;
};
class Base
{
public:
virtual ~Base() throw();
virtual DoWork() = 0;
};
class DerivedA : public Base
{
public:
DerivedA(std::unique_ptr<AppSpecificImp> appImp)
: imp(std::move(appImp))
{
}
void DoWork() override
{
// DerivedA specific code
imp->DoWork();
}
private:
std::unique_ptr<AppSpecificImp> imp;
};
class DerivedB : public Base
{
public:
DerivedB(std::unique_ptr<AppSpecificImp> appImp)
: imp(std::move(appImp))
{
}
void DoWork() override
{
// DerivedB specific code
imp->DoWork();
}
private:
std::unique_ptr<AppSpecificImp> imp;
};
Edit to show Visitor pattern usage:
With visitor pattern you can do what you want but with more Effort.
class Visitor
{
public:
virtual void VisitDerivedA(DerivedA* object) = 0;
virtual void VisitDerivedB(DerivedB* object) = 0;
};
class Base
{
public:
virtual void Visit(Visitor* visitor) = 0;
};
class DerivedA : public Base
{
public:
virtual void Visit(Visitor* visitor)
{
visitor->VisitDerivedA(this);
}
};
class DerivedB : public Base
{
public:
virtual void Visit(Visitor* visitor)
{
visitor->VisitDerivedB(this);
}
};
class AppSpecificVisitor : public Visitor
{
public:
void VisitDerivedA(DerivedA* object)
{
// Do any work related to DerivedA class
}
void VisitDerivedB(DerivedB* object)
{
// Do any work related to DerivedB class
}
}
int main()
{
AppSpecificVisitor myVisitor;
Base* myBase = // any class in your hierarchy
myBase->Visit(&myVisitor);
}
As I said in comments with Visitor pattern you can add new functionally without changing the main hierarchy(Base->Derived types). You just define a new visitor implementation and write your logic for every class in main hierarchy. In your example you can pack app specific logic in an object and reference that in your derived objects that is an easier approach.
Why not using a new set of hierarchy for application specific implementation ?
class AppBase
{
public:
virtual ~AppBase() throw();
virtual void work_with_app() = 0;
};
class Base
{
public:
Base(AppBase& app) : m_app(app) {}
virtual ~Base() throw();
protected:
AppBase& m_app;
};
class DerivedA : public Base { DerivedA(AppBase& app) : Base(app) {} };
class DerivedB : public Base { DerivedA(AppBase& app) : Base(app) {} };
// Application specific implementation :
class AppLuaSpecific : public AppBase
{
public:
void work_with_app() { /* Lua app specific */ }
};
This way, your 1st hierarchy : Base, DerivedA, DerivedB can live without knowing anything about the app specific code implemented in AppLuaSpecific.
You can implement your own app-specific dispatch as follows (check it live on Coliru):
#include <iostream>
#include <typeinfo>
struct Base { virtual ~Base() {} };
struct DerivedA : public Base { };
struct DerivedB : public Base { };
namespace AppSpecific
{
template<class F>
void dispatch(const Base& b)
{
const std::type_info& t = typeid(b);
if ( t == typeid(DerivedA) )
F::doit(static_cast<const DerivedA&>(b));
else if ( t == typeid(DerivedB) )
F::doit(static_cast<const DerivedB&>(b));
}
struct Foo
{
static void doit(const DerivedA& da) { std::cout << "Foo(DerivedA)\n"; }
static void doit(const DerivedB& db) { std::cout << "Foo(DerivedB)\n"; }
};
struct Bar
{
static void doit(const DerivedA& da) { std::cout << "Bar(DerivedA)\n"; }
static void doit(const DerivedB& db) { std::cout << "Bar(DerivedB)\n"; }
};
} // namespace AppSpecific
int main()
{
DerivedA da;
DerivedB db;
Base& b1 = da;
Base& b2 = db;
AppSpecific::dispatch<AppSpecific::Foo>(b1);
AppSpecific::dispatch<AppSpecific::Foo>(b2);
AppSpecific::dispatch<AppSpecific::Bar>(b1);
AppSpecific::dispatch<AppSpecific::Bar>(b2);
}

Using CRTP with virtual inheritance

I have a hierarchy of nodes, where "diamond" can occurred.
Every node must be clonable but I don't want to write clone method to every node. So I use CRTP.
class Node
{
public:
Node(){}
Node(Fill*) { }
virtual ~Node() {}
virtual Node * clone() const = 0;
virtual void id() { std::cout << "Node\n"; }
};
//====================================================================
template <typename Base, typename Derived>
class NodeWrap : public Base
{
public:
NodeWrap() { }
NodeWrap(Fill * arg1) : Base(arg1) { }
virtual Node *clone() const
{
return new Derived(static_cast<Derived const &>(*this));
}
};
works as follows:
class NodeA : public NodeWrap<Node, NodeA>
{
public:
typedef NodeWrap<Node, NodeA> BaseClass;
NodeA() { }
NodeA(Fill * f) : BaseClass(f) { }
virtual void id() { std::cout << "NodeA\n"; }
};
First question:
There is know BUG in VS when "covariance is used with virtual inheritance".
Is there a way to overcome the bug, and still have covariant types is clone method?
I changed return type to be Node instead of Base. I can live with that, but I would like to have Base as return type
Second question:
Problem occurred when multiple inheritance comes to play. I created new wrapper, which inherits virtually
template <typename Base, typename Derived>
class NodeWrapVirtual : public virtual Base
{
public:
NodeWrapVirtual() { }
NodeWrapVirtual(Fill * arg1) : Base(arg1) { }
virtual Node *clone() const
{
return new Derived(static_cast<Derived const &>(*this));
}
};
and now building diamond structure:
class NodeB : public NodeWrapVirtual<Node, NodeB>
{
public:
typedef NodeWrapVirtual<Node, NodeB> BaseClass;
NodeB() { }
NodeB(Fill * f) : BaseClass(f) { }
virtual void id() { std::cout << "NodeB\n"; }
};
//====================================================================
class NodeC : public NodeWrapVirtual<Node, NodeC>
{
public:
typedef NodeWrapVirtual<Node, NodeC> BaseClass;
using BaseClass::clone;
NodeC() { }
NodeC(Fill * f) : BaseClass(f) { }
virtual void id() { std::cout << "NodeC\n"; }
};
and problematic diamond node:
class NodeD : public NodeWrap<NodeB, NodeD>,
public NodeWrap<NodeC, NodeD>
{
public:
typedef NodeWrap<NodeB, NodeD> BaseClassB;
typedef NodeWrap<NodeC, NodeD> BaseClassC;
NodeD() { }
NodeD(Fill * f) : BaseClassB(f), BaseClassC(f) { }
using BaseClassB::clone; // (1)
virtual NodeD *clone() const { return new NodeD(*this); } // (2)
virtual void id() { std::cout << "NodeD\n"; }
};
where are 2 lines I am curious about. (line (1) and (2))
If both lines are removed, there is oblivious compile error, because there is ambiguous clone method (from every parent). Since I don't use covariant return types, there should work clone method form each parent, so i use line (1) but it doesn't work. Still ambiguous.
So I use line (2) and it works.
Is there a nice way, to avoid writing line (2)?
HERE is full working example on ideone.
First you should be very carefull to use virtual inheritance with members inside the virtual base (look at https://stackoverflow.com/a/1193516/1918154, "Effective C++", item 20: "Avoid data members in public interfaces" and http://www.parashift.com/c++-faq-lite/multiple-inheritance.html#faq-25.8). Your node gets an pointer to a fill which is not used, but it looks like you need it somewhere.
Your problem can be solved when you move the inhertance relationship (public virtual and public) in the base class for your NodeWrap.
template <typename Base>
class InheritVirtual
: public virtual Base
{};
template <typename... Bases>
class InheritBases
: public Bases...
{
virtual Node* clone() const = 0;
virtual void id() const = 0;
};
class NodeB : public NodeWrap<InheritVirtual<Node>, NodeB>
{
//...
};
class NodeC : public NodeWrap<InheritVirtual<Node>, NodeB>
{
//...
};
class NodeD : public NodeWrap<InheritBases<NodeB,NodeC>, NodeD>
{
//...
};
Running Example.
The pure virtual methods in InheritBases are needed because the so called domination rule (Dominance in virtual inheritance).
The problem to be solved is a way to transfer paramters to the right constructor in case of multiple bases. Unlike Node (wich is a virtual base) it is ok to let NodeB and NodeC have member variables and non trivial constructors.
Each virtual function must have a unique final overrider in each derived class. This has nothing to do with name lookup (the requirement is for the functions, not for their names), thus using is irrelevant.
Use a multi-base-classed node class template:
template <class Derived, class Base1, class Base2>
class node2 : // etc
// or use a variadic template if you have more than two bases
As for covariant returns, they are strictly unnecessary, if convenient. You can always split each virtual function into a private virtual and a public non-virtual. This comes handy if you want to return covariant smart pointers, which is not supported by the regular covariant return machinery at all.

Statically Init a derived class

With c++, Is there a way to get a derived class to inherit its own static initializer? I am trying to do something like the following:
class Base {
public:
class StaticInit {
public:
virtual StaticInit() =0;
};
};
class Derived: public Base {
public:
virtual StaticInit::StaticInit() {
//do something with the derived class
}
static StaticInit init;
}
static Derived::StaticInit init;
it would also be nice if I didn't have to define the init var in each derived class. I am currently redefining the StaticInit internal class in each derived class but it seems redundant.
Each derived class is a singleton, and I need the instance to be stored in a lookup table at program startup.
I use templates to do this, rather than inheritance - something like:
template <typename T>
struct StaticInit {
StaticInit() {
// do whatever with T
}
};
in use:
static StaticInit <SomeClass> init;
Use the CRTP:
template <class D>
class Base {
public:
class StaticInit {
public:
StaticInit() { D::initStatic(*this); }
};
static StaticInit init;
};
template <class D>
Base<D>::StaticInit init;
class Derived: public Base<Derived> {
public:
initStatic(Base<Derived>::StaticInit& s) {
// Do derived-specific initialisation on s.
}
}

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();
}