如何使用QObject派生类实例跟踪OOP基本概念?

时间:2014-05-08 21:46:35

标签: qt oop parent-child qobject qmetaobject

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

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

  2. 为什么Qt开发人员会在公共区域留下这样的功能? 他们试图达到什么目的?

  3. 关于我能想象的这些功能的唯一一个论点是与“垃圾收集”相关联。在Qt中(当一个删除父QObject派生类实例时,所有子实例都被自动删除)。但我认为可以用Qt的metaObject系统来完成(我在机制中不确定,但是,根据我的意见,访问儿童对象不应该是公开的)。

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

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

      虽然您可以使用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的任何子成员的状态,并且您可以实现任何类型的错误(例如行为根据{{​​1}}实施,这是不可能的。

      @ Merlin069:在Qt开发中,pImpl是一种常见的方法吗?

1 个答案:

答案 0 :(得分: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()访问。

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

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

现在,如果我们真的想要保持封装并使用QObject父系统,我们可以使用私有实现(pimpl)来实现,你可以read about here。另外,在内部,Qt uses this too