C++ tips

Here are some extra tips for C++ you could find useful.


Something about C++ *pointers and &references

You might notice a lot of objects are not initialized with the keyword new, nor have a *-operator at their name. Most of the time you just see Object name(arguments);. Such object is created at the "function stack". They are destroyed automatically when the function returns, which is a nice way to handle temporary objects.

References

A reference (prefixed by an &) tells a function where to find the object in the memory. This is used to pass objects to methods, and returning objects initialized as class/instance variable. Instead of copying the entire object at the stack, a reference is passed along so all methods access the same data. This technique is mostly used for objects initialized as stack variable; an invoked method can access the object directly by accessing the local stack variable.

When a referenced object is assigned to a local variable, it's contents is copied to the local variable. An example is:

QString name = mimeMessage.getValue("Invitation-Cookie");

The getValue() method returns a const QString &. The result is stored in a local QString, thereby copying the contents of the object. This is not a bad thing to do. Qt defines so-called shared classes which can be passed around like normal variables without losing much performance.

Pointers

A pointer variable (prefixed by an *) gives more freedom and should be handled with care. A pointer variable contains the memory address where the actual object can be found. This address can be shared between classes and functions, until someone decides to delete the object. Such objects are initialized with the keyword new, for example: KMess *kmess = new KMess();. The methods of a pointer variable are called with the -> operator, like kmess->initialize();.

Always ensure the calls to new and delete are balanced. Not deleting a pointer results in a memory leak. Deleting a pointer twice causes a crash. As rule of thumb, never return a object locally created with new. Always make sure one class manages the object; both creating and destroying it. If you have to return an object, return a copy (by not including the * or & prefix), or return a "const reference". C++ does not have a null keyword like Java does. Use the value 0 (zero) instead. Use something like if( object != 0 ) when the pointer might be null, because calling a method on a null-pointer causes a crash. Deleting a null-pointer causes no harm, but never forget to assign the value 0 to the variable afterwards. The delete command does not do this.

Most Qt classes automatically delete their children, so it's not that hard to manage large collections of objects. Sometimes we use the deleteLater() method to remove an object. This adds a delete request to the event-loop, removing the object once all pending events/signals are delivered. This avoids crashes that would occur otherwise.

Also note deleteLater() should not be called before a KMessageBox statement. Such dialog creates it's own event loop, so deleteLater is executed immediately.

QPixmap versus QImage

In the code you'll encounter both QPixmap and QImage objects. The difference between these objects is subtle but important to know. A QImage object loads the image in the system memory. It's optimized for manipulating the image. The QPixmap loads the image into the X server (or uploads it for remote X sessions).