Hey everyone,

I am currently working on a project to create a List ADT that has the following public interface:

+ size( ) : integer
o Returns the number of elements currently stored in the list.
o Postcondition: Returns 0 if empty otherwise returns the number of elements.
+ add( element: ElementType )
o Add an element to the list.
o Precondition: “element” does not already exist in the list. This is to say: no duplication allowed.
o Postcondition: “element” has been added to the end of the list.
o Throws an exception if “element” already exists in the list.
+ remove( element: ElementType ) : ElementType
o Remove this element from the list.
o Precondition: List is not empty.
o Postcondition: If the element is found in the list, it is removed from the list and returned. If the element is not found in the list, “null” is returned.
o Throws an exception if list is empty.
+ removeAll( )
o Remove all elements from the list.
o Postcondition: size( ) returns 0.
+ get( element: ElementType ) : ElementType
o Returns this element.
o Precondition: List is not empty.
o Postcondition: If the element is found in the list, it is returned. If the element is not found in the list, “null” is returned.
o Throws an exception if list is empty.


I want to make my implementation as flexible as possible in terms of the “type” of the elements in the list.Also make use of “typedef” and implement the List ADT using a reference or pointer-based data structure.

And make unit test of the ADT class .

Here is what I got so far and I am not sure if i am doing it right.So i would appreciate it if you help me figure this out.

Thanks,

Your use of exception specifications is well intended, but impractical, especially for a generic class. In Herb Sutter's words, "Don't bother. Even experts don't bother.". The same goes for Boost developers. Here is an in-depth look at this issue. Just don't do it.

Second, whenever making generic types, you should use nested typedefs for just about any type used in your class. This avoids the maintainability nightmare of having to go through your entire code if you suddenly decide to change one of the types.

Finally, if you are going to be diligent and write good comments for each function, you might as well use doxygen tags (they are more descriptive, standard, used to generate automatic documentation of your code, and supported by most IDE for documentation and code highlighting).

With there recommendations, your list.h file could look like this:

#ifndef LIST_H
#define LIST_H

#include "ListOutOfExceptedRange.h"
#include "ListException.h"

//#pragma once //don't use non-standard compiler extensions.

// declaration of the class
template <typename T>
class list
{
public:
   typedef T value_type;
   typedef T& reference;
   typedef const T& const_reference;
   typedef std::size_t size_type;
   typedef std::ptrdiff_t difference_type;

   /// Default constructor.
   list();
   
   /**
    * Determines whether a list is empty.
    * \pre None.
    * \post Returns true if the list is empty,
    *       otherwise returns false.
    * \return True if the list is empty, false otherwise.
    * \throw None.
    */
   bool isEmpty() const;

   /**
    * Returns the number of elements currently stored in the list.
    * \pre None.
    * \post Returns 0 if empty otherwise returns the number of elements.
    * \return Returns 0 if empty otherwise returns the number of elements.
    * \throw None.
    */
   size_type size() const;

   /** Returns the element at an index.
    * \pre List is not empty.
    * \post If the element is found in the list, it is returned. If the element is           
    *       not found in the list, null is returned.
    * \param index the index of the element.
    * \return the element at the given index.
    * \throw ListOutOfExceptedRange If list is empty.
    */
   const_reference get(size_type index) const;

   /**
    * Add an element to the list.
    * \pre The element does not already exist in the list. 
           This is to say: no duplication allowed.
    * \post The element has been added to the end of the list.
    * \param index the index where to add the element.
    * \param newItem the value of the new element to add to the list.
    * \throw ListOutOfExceptedRange if the list is empty.
    * \throw ListException if element already exists in the list.
    */
   void add(size_type index, const_reference newItem);

  /**
   * Remove this element from the list.
   * \pre List is not empty.
   * \post If the element is found in the list, it is removed from the list 
   *       and returned. If the element is not found in the list, null is returned.
   * \param index the index of the element to be removed.
   * \throw ListOutOfExceptedRange if list is empty (or index is out-of-range).
   */
   void remove(size_type index);
  
  /**
   * Remove all elements from the list.
   * \pre None
   * \post size() returns 0 and empty() return true.
   * \throw None
   */
   void removeAll();
};

#endif