Keagansed Keagansed - 2 months ago 15
C++ Question

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.

Answer

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.