Qt 和 C++:双重继承与组合?

Posted

技术标签:

【中文标题】Qt 和 C++:双重继承与组合?【英文标题】:Qt and C++ : double inheritance vs composition? 【发布时间】:2012-07-21 03:00:59 【问题描述】:

我的问题如下。我想制作一个新的小部件,它是 QTableWidget + QMenuBar(具有 QTableWidget 的特定配置)。目前,我创建了一个 MyWidget,它派生自 QWidget 并包含一个 QTableWidget + 一个 QMenuBar。但是是否可以通过从QTableWidgetQMenuBar 派生MyWidget 来做同样的事情?如果可能的话,构造函数是什么样的?

【问题讨论】:

【参考方案1】:

由于 QTableWidget 和 QMenuBar 都继承自 QWidget,我强烈建议不要使用双重继承。例如,请参阅this question。

您目前所做的通常被认为是“正确”的方式,至少在 Qt 中是这样。我怀疑你想使用多重继承而不是组合的主要原因是你可能觉得你必须编写一堆函数,以便使用你的小部件的人可以添加到 QMenuBar。这样的函数可能如下所示:

QAction *MyWidget::addMenuToMyQMenuBar(QMenu *menu)

    return myMenu->addMenu(menu);

对我来说这有点傻,相反我建议你简单地为你的 QMenuBar 创建一个访问器函数:

QMenuBar *MyWidget::menuBar()

    return myMenu;

现在使用您的课程的人可以这样做

myWidget->menu()->addAction(someAction);

这种编码风格在 Qt 源代码中很常见,我认为它更简洁。

【讨论】:

+1,很好的链接。并且深入了解 Qt 源代码中的惯用语【参考方案2】:

这听起来像组合将满足您的需求。

继承满足is-a关系(NewWidget是QTableWidget而NewWidget是QMenuBar?) 组合满足has-a关系(NewWidget有QTableWidget,NewWidget有QMenuBar?)

【讨论】:

【参考方案3】:

一次从两个 QWidget 继承是不可能的。每个 QWidget 也是一个 QObject。 MOC(元对象编译器)无法处理此类。

【讨论】:

【参考方案4】:

继承 - 关系是 X isa Y

Composition - 关系是 X 有一个 Y

这就是你的答案——X 和 Y 之间的关系是什么?

【讨论】:

没那么简单。 C++ 继承和类的设计听起来像“X 就像 Y”,而不是“X 是 Y”(这只是一种特殊情况)。真正的问题是,这两个基础都有共同的基础,而不是设计为共享的。因此,组合是唯一的出路。但它是 QT 设计者的选择,发生在 OOP 是用 C++ 编写类的唯一方式时。 你只是一颗钻石——见en.wikipedia.org/wiki/Diamond_problem。我同意,这就是为什么 Java 等使用接口来克服这种情况的原因。 不,我不花那么多钱 :-)) 出于讽刺,在某些实践中可能是这样,但定义不同:C++ 类只有在以下情况下才能形成“钻石” base 是虚拟的(菱形本身就是一种可管理的模式:可能不是 OOP 学校的最爱,但仍然是可管理的)。 QT 不是这样设计的。 Java 接口也只是“dimanond facets”(只是您看不到这一点,因为您没有访问后面的公共共享对象)。只是代码更重复。你如何在java中继承(原谅撰写)多个接口实现? Emilio - Java 你说这个调用实现了 X、Y 和 Y - 但归根结底只有一个函数。 这个论点更复杂,并且超出了这个问题的目的。单继承+接口不具备多继承的表现力(但对于经验不足的程序员来说“更安全”)。等效性还需要对嵌入式对象的隐式转发能力。关键是要了解已经编写的代码的“可重用性”背后的原因。接口(因为不携带代码)不是一个很好的例子。但这使我们与初衷相去甚远......

以上是关于Qt 和 C++:双重继承与组合?的主要内容,如果未能解决你的问题,请参考以下文章

C++ 继承:父子类赋值转换菱形继承虚继承继承与组合

8-5:C++继承之多继承,菱形继承,虚继承,虚基表,继承和组合

[C++]——继承赋值兼容规则与组合 (这一篇就够了!)

[C++]——继承赋值兼容规则与组合 (这一篇就够了!)

[C++]——继承赋值兼容规则与组合 (这一篇就够了!)

C++ COM 设计。组合与多重继承