多重继承和单例设计模式

时间:2016-10-03 13:33:23

标签: c++ inheritance design-patterns singleton static-variables

我设置了以下类层次结构,并希望调用非单例基础对象 text.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,long arg3) { // TODO Auto-generated method stub Toast.makeText(getApplicationContext(),(CharSequence)arg0.getItemAtPosition(arg2), Toast.LENGTH_LONG).show(); } }); 的{​​{1}}函数,然后从其中一个调用print()子类,在这种情况下OtherBase。我理解这是一个复杂的,有点不必要的层次结构和做事方式,但这是一个任务,我需要这样做。

我的问题的一个例子如下:

printSymbol()

如何让实例SingletonChild调用一个基类#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; } 而不是Singleton基类test的{​​{1}}函数?

我尝试了print,但这不起作用。

3 个答案:

答案 0 :(得分:3)

@ MuhammadAhmad的答案基本上是正确的。我想补充一点,这里的主要问题是C风格的演员阵容允许你做一些你真的不想做的事情。因为您无法将SingletonBase静态转换为OtherBase,所以C样式转换正在执行reinterpret_cast,并且在结果指针上调用print()是未定义的行为。如果您使用了static_cast,则会出现错误:

OtherBase* test = static_cast<OtherBase*>(SingletonChild::instance());
  

错误:从类型'SingletonBase *'中的static_cast无效到类型'OtherBase *'

这可能会让你意识到你需要做的事情有点不同。例如,您可以使用dynamic_cast像这样横向投射。

答案 1 :(得分:2)

SingletonChildinstance继承了SingletonBase方法,该方法返回指向SingletonBase的指针。
因此,调用SingletonChild::instance();会为您提供一个SingletonBase*,您无法将其转换为OtherBase*

首先尝试将其投放到SingletonChild*,然后投放到OtherBase*

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

然后简单地调用print方法:test->print();

请参阅code on ideone

修改

你也可以这样做:

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

另见this method in action

答案 2 :(得分:1)

您要做的是将类型为SingletonBase *的对象转换为OtherBase*类型,不可能,因为SingletonBase不是从{{1}派生的}。如果您使用过OtherBase而不是旧的,已弃用的C风格的强制转换,那么您可能会立即认识到这种情况。

要解决此问题,您需要按如下方式修改代码:

dynamic_cast

你应该避免使用C风格的强制转换,因为你可能最终操纵对象就像它们不是。