接口如何返回未知类型?

问题描述 投票:0回答:1

我想让一个cpp接口类(纯虚拟)声明一个所有派生类都必须实现的函数。 但是由于接口类想不知道实现细节,所以不知道返回对象的类型,想委托给派生类。 返回对象的具体类型由派生类处理。

class UIInterface 
{ 
    // Should not know about QWidget
    // Would like to defer return type until derived class which implements interface
    QWidget *getWindow() = 0;
}

class QUIManager : public UIInterface 
{
    QWidget *getWindow() override {return m_widget;} 
}

class XUIManager : public UIInterface 
{
    XWidget *getWindow() override {return m_widget;} 
}  

除了 UIInterface 不该知道 QWidget. 在未来的一些版本中, UIManager 或为 XUIManager 返回一个不同类型的窗口。 如果可能的话,我希望避免返回 std::anyvoid * 后面是铸造。

这种模式一直出现在我的代码中,所以我可能做错了什么。

根据评论进行编辑。

我的代码是实验性的,所以虽然我现在使用Qt作为UI,但可以想象,这可能会改变,比如使用一个即时模式包,或者在任何情况下,将核心逻辑和UI分开。 例如,核心逻辑,可能只从一个控制台访问,没有UI。 同样,我也在使用Qt的modelview和数据库类。

举一些例子。

  • 核心需要告诉UI打开和关闭窗口。 我在大多数情况下得出结论,核心不需要盲目洗牌裸露的UI指针,所以也许这个用例已经不是那么重要了。
  • 核心需要能够将数据库、模型和视图粘合在一起,而这后三个项目之间互不相识,即使后三个项目可能都是Qt或其他框架所特有的,或者是拆分的,比如单独使用sqlite3,将modelview委托给Qt。 比如核心需要告诉数据库接口打开一个sqlite3文件,要求modelcreator在此基础上创建一个模型,然后把模型传给UIManager创建视图。 在任何情况下,核心都不需要知道具体的类型,可能把指针传来传去就够了,但这似乎不是现在C++的方式。
  • 虽然目前轨道是C++,但在某些时候,核心本身可能会用更适合核心算法函数的语言来实现,比如Julia、Common Lisp等,这会带来与Qt的阻抗不匹配,所以我在尽力保证核心可以盲目调用一些高级函数,同时还能作为应用的中心枢纽。
c++
1个回答
0
投票

在我的脑海里有两种选择,这要看什么更适合你的项目。

1) 使用一个返回类型的占位符。

class UIInterface 
{ 
    Widget* getWindow() = 0;
}

你可以在其他文件中定义 using Widget = QWidget. 你可以更改别名,甚至可以实现你的类。Widget 后来居上 UIInterface 将不会改变。在这种情况下,你只是将真正的类型隐藏在你的类的布局中。

2) 你应该使用一个模板类,如

template<typename T>
class UIInterface 
{ 
    T* getWindow() = 0;
}

但2号的缺点是:你不能再使用 UIInterface 作为接口,而不指定 T而你实际上是在说QWidget 是具体类型的 T 在您的代码中。

既然你写了 "将来界面可能会改变" 而不是 "无论具体的部件类型如何,我都会创建一个接口",我想更适合你的选项是No.1。

© www.soinside.com 2019 - 2024. All rights reserved.