Search code examples
c++inheritancedesign-patternssingletonstatic-variables

Multiple inheritance and singleton design pattern


I have the following class hierarchy set up and would like the print() function of the non-singleton base object OtherBase to be called which in turn calls the printSymbol() from one of the child classes, in this case SingletonChild. I understand this is a complicated and somewhat unnecessary looking hierarchy and way of doing things but this is an assignment and I am required to do it in this way.

An example of my problem is as follows:

#include <iostream>
using namespace std;

class Object
{
    virtual void print() = 0;
};

class SingletonBase : public Object
{
private:
    static SingletonBase* theOnlyTrueInstance;
protected:
    SingletonBase()
    {
        if(!theOnlyTrueInstance)
            theOnlyTrueInstance = this;
    }
    virtual ~SingletonBase(){}
public:
    static SingletonBase* instance()
    {
        if (!theOnlyTrueInstance) initInstance();
        return theOnlyTrueInstance;
    }
    void print()
    { cout<<"Singleton"<<endl; }
    static void initInstance()
    { new SingletonBase; }
};

SingletonBase* SingletonBase::theOnlyTrueInstance = 0;

class OtherBase : public Object
{
public:
    virtual string printSymbol() = 0;
    void print()
    { cout<<printSymbol(); }
};

class SingletonChild : public SingletonBase , public OtherBase
{
public:
    string printSymbol()
    {
        return "Test";
    }
    static void initInstance()
    { new SingletonChild; }
};

int main() {
    SingletonChild::initInstance();
    OtherBase* test = (OtherBase*) SingletonChild::instance();
    test->print();
    return 0;
}

How can I get the instance test to call the print function of the one base class OtherBase and not the Singleton base class SingletonBase?

I have tried test->OtherBase::print(), but this did not work.


Solution

  • SingletonChild is inheriting it's instance method from SingletonBase, which is returning a pointer to SingletonBase.
    So calling SingletonChild::instance(); will get you a SingletonBase*, which you can't simply cast to OtherBase*

    Try casting it to SingletonChild* first, then to OtherBase*:

    OtherBase* test = (OtherBase*)((SingletonChild*)SingletonChild::instance());
    

    And then call the print method simply like this: test->print();

    See the code on ideone.

    EDIT:

    You can also achieve this like this:

    SingletonChild* test = (SingletonChild*)SingletonChild::instance();
    test->OtherBase::print();
    

    See this method in action too.