3

大家好...我使用 Qt 的时间不长,但最近我想到了一个想法。 QObject具有公共函数children()和其他一些函数,它们返回指向子对象的指针。所以自定义类的任何客户端都可以打破封装

  1. 如何保护我的代码免受这种野蛮对待?

  2. 为什么 Qt 开发人员将这些功能留在公共部分?他们试图达到什么目的?

我能想象到的关于此类函数的唯一一个论点与 Qt 中的“垃圾收集”有关(当一个删除父QObject派生类实例时,所有子实例都会被自动删除)。但我认为这可以通过 Qt 的metaObject系统来完成(我不确定机制,但是,在我看来,对子对象的访问不应该是公开的)。

  1. 另外,考虑当有人试图在单独的线程中使用子对象时的情况,这在 Qt 中是被禁止的......但我没有看到使用QObject::children().

//------------------------------------------------ ------------------------------------------------

根据一些评论进一步解释:

虽然您可以访问QObject::children()班级的私人成员,例如

class MyClass: public QWidget{ private: QLabel* m_lbl1; };
...
MyClass* p = new MyClass;
QLabel* pLbl = p->findChild<QLabel>();

无需将成员 m_lbl1 声明为私有成员:

class MyClass: public QWidget{ public: QLabel* m_lbl1; };

这是非常糟糕的。因为如果您的解决方案中至少有 10^5 行代码并且超过 1 个开发人员,迟早有人可以手动更改任何子成员的状态MyClass,您可以实现任何类型的错误(例如,根据实施MyClass)。

@Merlin069:pImpl 是 Qt 开发中的常用方法吗?

4

1 回答 1

3

Qt 对象的父系统非常有用,但我想我明白你得到了什么。

例如,假设这里声明的所有对象都是从 QObject 派生的:-

class MyClass : public QObject
{
    Q_OBJECT

    private:
        SomeOtherClass* m_pOtherClass = nullptr; // C++ 11 initialisation
};

在 MyClass 的构造函数中...

m_pOtherClass = new SomeOtherClass(this);

因此,我们现在有了封装的 SomeOtherClass 对象,但由于它的父对象是 MyClass,因此也可以通过 MyClass 中的函数 children() 访问它。

如果你想在这里封装,那么你可以牺牲使用父/子层次结构并声明 SomeOtherClass 与 NULL 父级。

但是,如果您考虑 Qt 对象树的原因,正如@deGoot 所提到的,那么它提供了这样一个有用的系统,其好处超过了打破封装。

现在,如果我们真的想维护封装并使用 QObject 父系统,我们可以使用私有实现 (pimpl) 来实现,您可以在此处阅读。此外,在内部,Qt 也使用它

于 2014-05-09T08:29:09.080 回答