[英]Multiple inheritance and singleton design pattern
我设置了以下类层次结构,并希望调用非单个基础对象OtherBase
的print()
函数,该函数printSymbol()
子类之一(在本例中为SingletonChild
printSymbol()
调用printSymbol()
。 我知道这是一种复杂且有些不必要的外观层次结构和处理方式,但这是一项任务,我需要以此方式进行处理。
我的问题的一个例子如下:
#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;
}
如何获得实例test
来调用一个基类OtherBase
而不是Singleton基类SingletonBase
的print
功能?
我试过了test->OtherBase::print()
,但这没有用。
@MuhammadAhmad的答案基本上是正确的。 我想补充一点,这里的主要问题是C风格的强制转换允许您执行您确实不想执行的操作。 因为您不能将SingletonBase
静态转换为OtherBase
,所以C样式转换将执行reinterpret_cast
,并且在结果指针上调用print()
是未定义的行为。 如果您使用了static_cast
,那么将得到一个错误:
OtherBase* test = static_cast<OtherBase*>(SingletonChild::instance());
错误:从类型'SingletonBase *'到类型'OtherBase *'的static_cast无效
这可能使您意识到需要做一些不同的事情。 例如,您可以使用dynamic_cast
这样横向投射。
SingletonChild
从SingletonBase
继承其instance
方法,该方法将返回指向SingletonBase
的指针。
因此调用SingletonChild::instance();
将为您提供SingletonBase*
,您不能简单地将其OtherBase*
为OtherBase*
尝试先将其转换为SingletonChild*
,然后转换为OtherBase*
:
OtherBase* test = (OtherBase*)((SingletonChild*)SingletonChild::instance());
然后像下面这样简单地调用print
方法: test->print();
编辑 :
您也可以这样实现:
SingletonChild* test = (SingletonChild*)SingletonChild::instance();
test->OtherBase::print();
实际也请参见此方法 。
您要尝试将类型为SingletonBase *的对象转换为类型OtherBase*
,这是不可能的,因为SingletonBase
并非派生自OtherBase
。 如果您使用dynamic_cast
而不是旧的,不推荐使用的C样式强制转换,那么您会立刻意识到这种情况。
要解决此问题,您需要修改代码,如下所示:
class Object
{
virtual void print() = 0;
};
class SingletonBase : public Object
{
private:
static Object* theOnlyTrueInstance;
protected:
SingletonBase()
{
if(!theOnlyTrueInstance)
theOnlyTrueInstance = this;
}
virtual ~SingletonBase(){}
public:
static Object* instance()
{
if (!theOnlyTrueInstance) initInstance();
return theOnlyTrueInstance;
}
void print()
{ cout<<"Singleton"<<endl; }
static void initInstance()
{ new SingletonBase; }
};
Object* 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 = dynamic_cast<OtherBase*>(SingletonChild::instance());
test->print();
return 0;
}
您应该避免使用C风格的强制类型转换,因为您可能最终会像对待对象一样操纵对象。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.