我如何与QObject派生类实例遵循OOP基本概念



大家好…我使用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行代码,并且多于一个开发人员,迟早有人可以手动更改MyClass的任何子成员的状态,并且你可以实现任何类型的bug(例如根据MyClass实现不可能的行为)。

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

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)来做到这一点,您可以在这里阅读。而且,Qt内部也使用这个

最新更新