3

Hi, all... I'm working with Qt not for a long time, but recently a thought came to my mind. QObject has public function children() and a few other ones, which return pointer to a child object(s). So any client of custom class can break encapsulation.

  1. How can I protect my code from such barbaric treatment?

  2. Why did Qt developers leave such functionality in public section? What purpose did they try to achieve?

The only one argument about such functions I can imagine is connected with 'garbage collection' in Qt (when one delete parent QObject derived class instance all children instances are automatically deleted). But I think it could be done with Qt's metaObject system (I'm not sure in the mechanism, however, access to child objets shouldn't be public, on my opinion).

  1. Also, consider situation when someone attempts to use child object in separate thread, which is forbidden in Qt... but I don't see any restrictions in light of using QObject::children().

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

further explanation according to some comments:

While you have access with QObject::children() to private members of the class, e.g.

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

there is no need to declare member m_lbl1 as private one:

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

and it's very bad. because if you have at least 10^5 lines of code in your solution and more that 1 developer, sooner or later someone can manually change state of any child member of MyClass and you can achieve any kind of bug (e.g. behavior which is not possible according to MyClass implementation).

@Merlin069: is pImpl a common approach in Qt's development?

1
  • I believe this is part of Qt's Object Trees architecture, which I personally find quite clever. I don't understand what you mean by "break encapsulation" or "protect your code from such treatment". Can you please elaborate? What "treatment" are you worried about? Please note that Qt is built on C++, which is not a "managed" language, so it's up to you to make sure that your code isn't treating anything "barbarically". Commented May 8, 2014 at 22:56

1 Answer 1

3

The Qt object's parent system is very useful, but I think I understand what you're getting it.

For example, assuming all objects declared here are derived from QObject:-

class MyClass : public QObject
{
    Q_OBJECT

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

In the constructor of MyClass...

m_pOtherClass = new SomeOtherClass(this);

So, we now have the encapsulated SomeOtherClass object, but as it's parent is MyClass, it's also accessible via the function children() from MyClass.

If you want encapsulation here, then you can sacrifice using the parent / child hierarchy and declare SomeOtherClass with a NULL parent.

However, if you consider the reason for Qt's Object Trees, as @deGoot mentions, then it provides such a useful system whose benefits outweigh breaking the encapsulation.

Now, if we really want to maintain encapsulation and use the QObject parenting system we can do so by using a Private Implementation (pimpl), which you can read about here. Also, internally, Qt uses this too.

Sign up to request clarification or add additional context in comments.

2 Comments

I've been finding that pimpl is the best way to achieve encapsulation in C++. If you "expose" your class's private members in a header file, someone can always break encapsulation using pointer manipulation.
Pimpl is heavily used by Qt. If you look at their source code (it is opensource after all), you will see that most private data is hidden in private objects which are referenced in the "public" object.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.