Saturday, September 6, 2014

RPN List – To Standard List

The RPN List class list member was changed from QList to std::list.  The largest part of this change is due to standard lists not being indexed by a simple integer like a QList (which is implemented as an array internally), but with iterators as the standard list is a double linked list internally.

The significant parts of this change include iterating over the items in the list (changing regular indexed for loops to C++11 range-for loops) where the get item at index function was removed and access to the list's constant begin and end iterators was added; updating the RPN List class access functions for adding to or inserting into the list; and updating the INPUT command translate function to handle an iterator for inserting input parse codes into the list instead of an index.  Click Continue... for details of these changes.

[branch cpp11 commit 9bca14b4b5]

RPN List – Base Class To Member

The next step is to replace the use of pointers to RPN lists.  Currently, an RPN list is allocated in the translator and decoder, a pointer to which is returned.  It is then the caller's responsibility to delete the RPN list.  This is the so called naked new and delete that can be problematic (cause memory leaks if not careful).  This could be another use for a shared pointer.  However, for this case, there is a another better C++11 solution.  This change involves several distinct parts.

During these changes, a problem was found upstream with the RPN List class that was misinterpreted as being caused by using a list class as a base class.  The list classes (QList or std::list) were not designed to be used as base classes.  The problem was perceived to be due to these classes not having virtual destructors, but this was not the case.  A bigger issue is that having the list class as a public base class opens up all of the public list class members for access to users of the RPN List class, which is not good object-oriented design.

Therefore, the first part of the next set of changes was to change from using the list class as a base class to having a list member variable.  Access functions to the list member were added, which includes getting the list size, checking if the list is empty, getting the token of the last item, getting an item at an index, and clearing the list.  There are already access functions for appending items to the list, comparing lists (equality operators), inserting into the list, and converting the list to text (for test output).

The Translator class also contained access functions to the output list (for the various external translate functions) and these were insured to call the RPN List class access functions instead of the list directly.  Only the output last token function needed to be modified since it was accessing the list directly.

Finally, the RPN List class destructor was calling the clear function of the list, but this is no longer necessary as this will happen automatically when each member (including the new list member) is destroyed.  This was necessary previously because of the problem mentioned above that the base list class destructor was not defined as virtual and therefore was not being called (the RPN List class destructor overrode the list class destructor).

[branch cpp11 commit 32ab971b45]