大家好,所有......我和Qt一起工作的时间不长,但最近我想到了一个想法。
QObject
具有公共函数children()
和其他一些函数,它们将指针返回给子对象。
因此,任何自定义类的客户都可以打破封装。
如何保护我的代码免受这种野蛮的待遇?
为什么Qt开发人员会在公共区域留下这样的功能? 他们试图达到什么目的?
关于我能想象的这些功能的唯一一个论点是与“垃圾收集”相关联。在Qt中(当一个删除父QObject
派生类实例时,所有子实例都被自动删除)。但我认为可以用Qt的metaObject
系统来完成(我在机制中不确定,但是,根据我的意见,访问儿童对象不应该是公开的)。
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
的任何子成员的状态,并且您可以实现任何类型的错误(例如行为根据{{1}}实施,这是不可能的。
@ Merlin069:在Qt开发中,pImpl是一种常见的方法吗?
答案 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。