Monday, September 1, 2014

RPN Item Pointers As Shared Pointers

An attempt was made to replace all the token pointers with a shared pointer class (QSharedPointer).  A lot of changes were required that created many compile issues to correct.  Worst, when running the first time, there were many crashes that were not being easy to resolve.  I believe some of the problems were related to the RPN items (that hold token pointers) stored in the RPN output list.  So, these changes were temporarily stashed.

Instead of starting with the token pointers, the simpler RPN item pointers were changed to use QSharedPointer.  This was successful, however, I decided to try using the STL std::shared_ptr class (C++11 only) instead .  After some testing, it appears that STL classes are faster than the equivalent Qt classes.

Originally, STL classes were avoided in favor of Qt classes, since this is a Qt based GUI application.  With the recent desire to use C++11 and considering that the STL classes were enhanced and optimized to use C++11, STL classes will now be used as much as possible except when dealing specifically with GUI elements requiring Qt classes or when Qt classes have features not available in the STL classes (for example, the STL std::string class does not have a case insensitive comparison, but the QString class does).

To start the changes for the RPN item pointers, all instances of RpnItem* were changed to RpnItemPtr, which was defined as an alias (this using syntax is new to C++11 and is just an easier form of the typedef statement):
using RpnItemPtr = QSharePointer<RpnItem>;
Many functions that had an RPN item pointer as an argument were changed to a reference to a RpnItemPtr so that the use count of the isn't unnecessarily incremented when a copy is made for the function call argument (and then decremented when the function returns).  If the item is copied inside the function, the use count will get incremented.  RPN items no longer need to be deleted as they now will be done automatically when they they go out of scope or their container is deleted or goes out of scope.

The RPN item constructor was changed to use the new initializer syntax instead of setting the member inside the constructor body.  This is more efficient because otherwise, the default constructor is first called for each non-plain member and then a value is copied into the member.  The RPN list class also no longer needed a clear function to delete the RPN items (the items get deleted automatically).

The attached array (with a count) in the RPN item class was naively implemented as a plain C array, which required naked new and delete operations and was changed to a QList.  This change eliminates the need for a count variable (QList maintains its size) and also eliminates the need to delete the attached RPN items (automatic when the RPN item is deleted automatically).

When the RPN item pointer was changed to the STL std::shared_ptr class, the changes with QSharedPointer were put on a branch and the branch abandoned.  The change in shared pointer class only required minor changes, which included changing the alias above and adding an alias for RPN item pointer vector:
using RpnItemPtr = std::shared_ptr<RpnItem>;
using RpnItemPtrVector = std::vector<RpnItemPtr>;
The latter alias is used for the attached member (just changed to a QList) was changed to a std::vector (which is more similar to QList than to std::list as QList is an allocated array, std::list a double-linked list).  Also, the size of STL classes is accessed using the size member function compared to the count member functions of the Qt classes.

[branch cpp11 commit a2069aae24]
[branch rpnitem-qt-sharedptr commit 7840954d5e]