2014-05-08 1 views
3

Salut, tous ... Je ne travaille pas avec Qt depuis longtemps, mais récemment une pensée m'est venue à l'esprit. QObject a la fonction publique children() et quelques autres, qui renvoient pointeur à un objet enfant (s). Ainsi, tout client de classe personnalisée peut rompre l'encapsulation.Comment puis-je suivre les concepts de base POO avec l'instance de classe dérivée QObject?

  1. Comment puis-je protéger mon code contre un tel traitement barbare?

  2. Pourquoi les développeurs Qt ont-ils laissé une telle fonctionnalité dans la section publique? Quel but ont-ils essayé d'atteindre?

Le seul argument de ces fonctions, je peux imaginer est liée à « la collecte des ordures » dans Qt (quand on supprimer parent QObject instance de classe dérivée tous les enfants instances sont automatiquement supprimés). Mais je pense que cela pourrait être fait avec le système metaObject de Qt (je ne suis pas sûr dans le mécanisme, cependant, l'accès aux objets enfants ne devrait pas être public, à mon avis).

  1. En outre, la situation considérer lorsque quelqu'un tente d'utiliser l'objet enfant dans thread séparé, ce qui est interdit dans Qt ... mais je ne vois aucune restriction à la lumière de l'utilisation QObject::children().

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

autre explication selon certains commentaires:

Pendant que vous avez accès à QObject::children() aux membres privés de la classe, par exemple

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

il n'y a pas besoin de déclarer m_lbl1 membre comme l'un privé:

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

et il est très mauvais. parce que si vous avez au moins 10^5 lignes de code dans votre solution et plus de 1 développeur, quelqu'un peut changer manuellement l'état de n'importe quel membre MyClass et vous pouvez réaliser n'importe quel type de bug (par exemple un comportement impossible selon la mise en œuvre MyClass).

@ Merlin069: pImpl est-il une approche courante dans le développement de Qt?

+0

Je crois que cela fait partie de l'architecture de [Qt's Object Trees] (http://qt-project.org/doc/qt-4.8/objecttrees.html), que je trouve personnellement très intelligente. Je ne comprends pas ce que vous entendez par «casser l'encapsulation» ou «protéger votre code d'un tel traitement». Pouvez-vous élaborer s'il vous plaît? De quel «traitement» vous inquiétez-vous? Veuillez noter que Qt est construit sur C++, qui n'est pas un langage "géré", donc c'est à vous de vous assurer que votre code ne traite rien "de façon barbare". – deGoot

Répondre

3

Le système parent de l'objet Qt est très utile, mais je pense que je comprends ce que vous obtenez.

Par exemple, en supposant que tous les objets déclarés ici sont dérivés de QObject: -

class MyClass : public QObject 
{ 
    Q_OBJECT 

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

Dans le constructeur de MaClasse ...

m_pOtherClass = new SomeOtherClass(this); 

Donc, nous avons maintenant l'objet du encapsulé, mais comme c'est parent c'est MyClass, c'est aussi accessible via la fonction children() de MyClass.

Si vous voulez encapsuler ici, vous pouvez sacrifier en utilisant la hiérarchie parent/enfant et déclarer SomeOtherClass avec un parent NULL. Cependant, si vous considérez la raison pour laquelle les arbres d'objet de Qt, comme @deGoot mentionne, alors il fournit un système si utile dont les avantages l'emportent sur la rupture de l'encapsulation. Maintenant, si nous voulons vraiment maintenir l'encapsulation et utiliser le système parental QObject nous pouvons le faire en utilisant une implémentation privée (pimpl), que vous pouvez read about here. En outre, en interne, Qt uses this too.

+1

J'ai trouvé que pimpl est le meilleur moyen d'obtenir l'encapsulation en C++. Si vous "exposer" les membres privés de votre classe dans un fichier d'en-tête, quelqu'un peut toujours rompre l'encapsulation en utilisant la manipulation du pointeur. – deGoot

+1

Pimpl est * fortement * utilisé par Qt. Si vous regardez leur code source (c'est opensource après tout), vous verrez que la plupart des données privées sont cachées dans les objets privés qui sont référencés dans l'objet "public". – deGoot

Questions connexes