您可以拥有与您继承的基类相同的类的私有成员吗?

Posted

技术标签:

【中文标题】您可以拥有与您继承的基类相同的类的私有成员吗?【英文标题】:can you have a private member of the same class as the base class you're inheriting? 【发布时间】:2009-10-21 08:17:16 【问题描述】:

我正在使用 Qt 库。我目前正在尝试创建自己的 QDockWidget(我的类正在继承)。现在我的班级有一个指向 QDockWidget 的指针。这甚至有意义吗?这是法律声明吗?有没有更好的方法将 QDockWidget 与我在 Qt 中的其他程序分开?我对如何实现新的 Dock Widget 有点迷茫。这是我的 QDockWidget 类的副本:

#ifndef DOC_MENU_WIDGET_H #define DOC_MENU_WIDGET_H #include "App_interface.h" #include <QObject> #include <QWidget> #include <QDockWidget> class Doc_menu_widget : public QWidget //Q_OBJECT public: Doc_menu_widget(App_interface *parent); ~Doc_menu_widget(); private: QDockWidget *dock_widget; ; #endif

【问题讨论】:

请注意,QDockWidget 和“指向QDockWidget 的指针”是两种完全不同的类型。 为什么不直接从 QDockWidget 派生?你想表达什么:(a) Doc_menu_widget IS-A QDockWidget --> 派生 (b) IS-IMPLEMENTED_IN_TERMS-OF QDockWidget(与PERFORMS-LIKE QDockWidget相同) --> 使用私有成员 【参考方案1】:

您似乎混淆了 IS-A 关系和 HAS-A 关系。

IS-A 关系通过继承实现。例如,QWidget IS-A QObject

HAS-A 关系由成员实现。例如,QWidget HAS-A 大小。

现在,您尝试开发的类与 QDockWidget 之间有什么关系?这将告诉您应该选择两者中的哪一个。

【讨论】:

两者兼有有什么问题? “Dock Widget”是一个“Widget”,但同时拥有另一个“Widget”(可能是子小部件或不同的“Widget”)并没有错。 在这种特殊情况下,QDockWidget 不可能有另一个 QDockWidget has-a 可以通过私有继承来实现。尽管通常最好将其视为“根据以下方式实现”。【参考方案2】:

你不应该这样做吗?

class Doc_menu_widget : public QDockWidget

    // ...
;

子类化QWidget 然后拥有一个私有的QDockWidget 属性当然是有意义的,但它可能不会帮助你实现“你自己的停靠小部件”(只要我理解正确)。您只能通过这种方式获取原始停靠小部件,并且可以将其放置在新小部件中的某个位置。

或者,如果您想从头开始实现 QDockWidget 的等价物,您可能不需要私有 QDockWidget

【讨论】:

【参考方案3】:

当然,为什么不呢。而且,如果您只是将 ptr 用于基类对象,则您没有任何 完全没有问题。

您为什么不首先直接从 QDockWidget 派生?

你想表达:

(a) Doc_menu_widget IS-A QDockWidget --> 派生

(b) IS-IMPLEMENTED_IN_TERMS-OF QDockWidget(与 PERFORMS-LIKE 相同) QDockWidget) --> 使用私有成员

【讨论】:

【参考方案4】:

如果您只需要为您的QMainWindow 创建一个QDockWidget*,大多数情况下您可以简单地创建一个实例并立即使用它:

QDockWidget* dock = new QDockWidget(this);
dock->setWindowTitle("My Dock Widget");
addDockWidget(Qt::LeftDockWidgetArea, dock, Qt::Vertical);

如果您想创建具有不同行为或外观的自定义QDockWidget,那么从QDockWidget 继承可能更方便:

#include <QDockWidget>

class MyDockWidget : public QDockWidget

Q_OBJECT
    // ...
;

拥有一个带有QDockWidget* 私有成员的单独类当然是完全可能且合法的,但在这种情况下这不是最常见的选择。 原因是您很可能希望您的类是 QDockWidgetis-a 关系)的变体,这意味着它应该具有所有公共方法,并且它的实例应该能够传递给询问QDockWidget 实例的方法(例如,您希望能够添加一个到QMainWindow)。

【讨论】:

以上是关于您可以拥有与您继承的基类相同的类的私有成员吗?的主要内容,如果未能解决你的问题,请参考以下文章

子类真的继承私有成员变量吗?

4月14日继承与多态

面向对向之继承和扫描顺序

继承

Java中类的继承与权限控制

详解C++中基类与派生类的转换以及虚基类