Qt Memory Management Mechanism

Source: Internet
Author: User

This article is first published on my homepage http://www.devbean.info and will be published directly there later. Now we have an article in Flex 4 and a series from C ++ to Objective-C. Thank you for your support!

A strong language always explicitly or implicitly contains the type information of an object when creating an object. That is to say, when a strong language allocates the object memory space, it will always be associated with the object type. In contrast, the weak type language does not. After the memory space is allocated, there are two ways to release the space: manually release, or use the garbage collector. C ++ requires developers to manually release memory space. The advantage of doing so is that developers have full control over the memory and know when to release the memory. Java uses the garbage collector. In the background, a thread constantly checks which objects are not used and can be recycled based on certain algorithms. In this way, developers can be freed from the underlying implementation, and they only need to focus on the business logic.

This article focuses on the memory management of Qt. Here we will use the Qt mechanism to implement a simple garbage collector.

C ++ Memory Management Mechanism

C ++ requires developers to manage their own memory. There are three policies:

The last is usually known as "Memory leakage" and is considered a bug. Therefore, we need to select which of the first two is more appropriate. Sometimes, the object created by delete is much easier than all its sub-objects. Sometimes, it is quite difficult to find the last object.

Qt Memory Management Mechanism

Qt can maintain the object hierarchy internally. For visual elements, this hierarchy is the relationship between child components and parent components. For non-visual elements, it is the subordination between an object and another object. In Qt, deleting a parent object deletes its sub-objects together. This helps reduce memory problems by 90% and forms a mechanism similar to garbage collection.

QPointer

QPointer is a template class. It is similar to a common pointer. The difference is that QPointer can monitor objects that dynamically allocate space and update objects when they are deleted.

 
 
  1. // QPointer is similar to a normal pointer.
  2. QDate * mydate = new QDate (QDate: currentDate ());
  3. QPointer mypointer = mydata;
  4. Mydate-> year (); //-> 2005
  5. Mypointer-> year (); //-> 2005
  6. // After the object is deleted, QPointer has different performances.
  7. Delete mydate;
  8. If (mydate = NULL)
  9. Printf ("clean pointer ");
  10. Else
  11. Printf ("dangling pointer ");
  12. // Output dangling pointer
  13. If (mypointer. isNull ())
  14. Printf ("clean pointer ");
  15. Else
  16. Printf ("dangling pointer ");
  17. // Output clean pointer

Pay attention to the above Code. After a original pointer is deleted, its value is not set to NULL, so it becomes a wild pointer. However, QPionter does not have this problem.

QObjectCleanupHandler

Qt object cleaner is an important part of automatic garbage collection. It can register many sub-objects and automatically delete all sub-objects when you delete them. At the same time, it can also identify whether a sub-object is deleted from its sub-Object List. This class can be used to clear classes that are not in the same level. For example, when a button is pressed, many windows need to be closed. Because the parent attribute of a window cannot be set to a button of another window, in this case, it is quite convenient to use this class.

 
 
  1. // Create an instance
  2. QObjectCleanupHandler * cleaner = new QObjectCleanupHandler;
  3. // Create a window
  4. QPushButton * w = new QPushButton ("Remove Me ");
  5. W-> show ();
  6. // Register the first button
  7. Cleaner-> add (w );
  8. // If the first button is clicked, delete itself
  9. Connect (w, SIGNAL (clicked (), w, SLOT (deleteLater ()));
  10. // Create the second button. Note that this button does not take any action.
  11. W = new QPushButton ("Nothing ");
  12. Cleaner-> add (w );
  13. W-> show ();
  14. // Create the third button to delete all
  15. W = new QPushButton ("Remove All ");
  16. Cleaner-> add (w );
  17. Connect (w, SIGNAL (clicked (), cleaner, SLOT (deleteLater ()));
  18. W-> show ();

In the code above, three windows with only one button are created. When the first button is clicked, it will delete itself through the deleteLater () slot. At this time, cleaner will automatically clear it from its own list. When the third button is clicked, cleaner is deleted. In this way, all unclosed windows are deleted.

Qt garbage collection

As the object becomes more and more complex, it is difficult to decide when to perform the delete operation when this object is used in many places. Fortunately, Qt has a good garbage collection mechanism for all classes inherited from QObject. There are many implementation methods for garbage collection, the simplest is reference counting, and the other is to save all objects. The two implementation methods are described in detail below.

Reference count

Application counting is the simplest implementation of garbage collection: every time an object is created, the counter is added with 1, and every time one is deleted, the number is reduced by 1.

 
 
  1. class CountedObject 
  2. public: 
  3.     CountedObject() 
  4.     { 
  5.         ctr=0; 
  6.     } 
  7.   
  8.     void attach() 
  9.     { 
  10.         ctr++; 
  11.     } 
  12.   
  13.     void detach() 
  14.     { 
  15.         ctr--; 
  16.         if(ctr <= 0) 
  17.             delete this; 
  18.     } 
  19. private: 
  20.     int ctr; 
  21. }; 

 

After each sub-object is created, the attach () function should be called to add 1 to the counter. When deleting the sub-object, the detach () function should be called to update the counter. However, this class is very primitive and there is no convenient Qt mechanism. The following is an implementation of the Qt version:

 
 
  1. class CountedObject : public QObject 
  2.     Q_OBJECT 
  3. public: 
  4.     CountedObject() 
  5.     { 
  6.         ctr=0; 
  7.     } 
  8.   
  9.     void attach(QObject *obj) 
  10.     { 
  11.         ctr++; 
  12.         connect(obj, SIGNAL(destroyed(QObject*)), SLOT(detach())); 
  13.     } 
  14.   
  15. public slots: 
  16.     void detach() 
  17.     { 
  18.         ctr--; 
  19.         if(ctr <= 0) 
  20.             delete this; 
  21.     } 
  22.   
  23. private: 
  24.     int ctr; 
  25. }; 

We use the Qt signal slot mechanism to automatically reduce the counter value when the object is destroyed. However, our implementation does not prevent two attach () calls during object creation ().

Record Owner

A more appropriate implementation is to remember not only several objects hold references, but also what objects they are. For example:

 
 
  1. Class CountedObject: public QObject
  2. {
  3. Public:
  4. CountedObject ()
  5. {
  6. }
  7. Void attach (QObject * obj)
  8. {
  9. // Check the owner
  10. If (obj = 0)
  11. Return;
  12. // Check whether it has been added
  13. If (owners. contains (obj ))
  14. Return;
  15. // Register
  16. Owners. append (obj );
  17. Connect (obj, SIGNAL (destroyed (QObject *), SLOT (detach (QObject *)));
  18. }
  19. Public slots:
  20. Void detach (QObject * obj)
  21. {
  22. // Delete
  23. Owners. removeAll (obj );
  24. // If the last object is deleted, delete itself.
  25. If (owners. size () = 0)
  26. Delete this;
  27. }
  28. Private:
  29. QList owners;
  30. };

Now our implementation can prevent an object from calling attach () and detach () multiple times. However, another problem is that we cannot guarantee that the object will call the attach () function for registration. After all, this is not a built-in mechanism of C ++. One solution is that the implementation of redefinition of the new operator is equally complicated, but it can avoid the case that some objects do not call attach () registration ).


This article comes from DevBean's World: http://www.devbean.info.
When reprinting, indicate the original source of the article: http://www.devbean.info/2011/03/qt_memory_management /.


This article is from the "bean space" blog, please be sure to keep this source http://devbean.blog.51cto.com/448512/526734

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.