C++ Full Project Create a templated queue class with an array based variant. An
ID: 3827726 • Letter: C
Question
C++ Full Project
Create a templated queue class with an array based variant.
An example header file below is given holding elements of type class DataType. This class should be templated
const int ARRAY_MAX = 1000;
class ArrayQueue{
public:
ArrayQueue(); //Instantiate a new Queue object with no valid data
ArrayQueue(int size, const DataType& value); // Instantiate a new Queue object which will hold int size number of elements in total, all of them initialized to be equal to parameter //value
ArrayQueue(const ArrayQueue& other); //Instantiate a new Queue object which will be a seperate copy of the data of the other Queue object which is getting copied
~ArrayQueue(); // Destroys the instance of the Queue object
ArrayQueue& operator=(const ArrayQueue& other_arrayQueue); // Will assign a new value to the calling Queue object, which will be an exact copy of the other_arrayQueue object //passed as a parameter. Returns a reference to the calling object to be used for cascading operator=
DataType& front(); //returns a reference to the front element of the queue (before calling this method ensure the queue isnt empty)
const DataType& front() const;
DataType& back(); //returns a reference to the back element of the queue (before calling this method ensure the queue isnt empty)
const DataType& back() const;
void push(const DataType& value); // Inserts at the back of the Queue an element of the given value
void pop(); //removes from the front element of the queue
int size() const; // returns the size of the current queue
bool empty() const; // will return true if the queue is empty
bool full() const; // will return true if the queue is full
void clear(); // after called the queue will be considered empty
friend std::ostream& operator<<(std::ostream& os, const ArrayQueue& arrayQueue); //will output the complete content of the calling queue object. (Not required to be templated)
private:
DataType m_array[ARRAY_MAX]; //The array that holds the data. Both parameters determined via template parameters
int m_front; // an int with the respective m_array index of the front element of the queue
int m_back; // an int with the respective m_array index of the last element of the queue
int m_size; // keeps track of how many elements are in the queue (should not exceed ARRAY_MAX)
};
/*The implementation will be a wrap around queue, meaning that,
a) pushing an element will move the back by one (m_back=(m_back+1)%ARRAY_MAXSIZE) //and increase the size by one
b) popping an element will move the front by one (m_front=(m_front+1)%ARRAY_MAXSIZE) // and decrease size by one
*/
Explanation / Answer
It is not possible to write the implementation of a template class in a separate cpp file and compile. All the ways to do so, if anyone claims, are workarounds to mimic the usage of separate cpp file but practically if you intend to write a template class library and distribute it with header and lib files to hide the implementation, it is simply not possible.
To know why, let us look at the compilation process. The header files are never compiled. They are only preprocessed. The preprocessed code is then clubbed with the cpp file which is actually compiled. Now if the compiler has to generate the appropriate memory layout for the object it needs to know the data type of the template class.
Actually it must be understood that template class is not a class at all but a template for a class the declaration and definition of which is generated by the compiler at compile time after getting the information of the data type from the argument. As long as the memory layout cannot be created, the instructions for the method definition cannot be generated. Remember the first argument of the class method is the 'this' operator. All class methods are converted into individual methods with name mangling and the first parameter as the object which it operates on. The 'this' argument is which actually tells about size of the object which incase of template class is unavailable for the compiler unless the user instantiates the object with a valid type argument. In this case if you put the method definitions in a separate cpp file and try to compile it the object file itself will not be generated with the class information. The compilation will not fail, it would generate the object file but it won't generate any code for the template class in the object file. This is the reason why the linker is unable to find the symbols in the object files and the build fails.
Now what is the alternative to hide important implementation details? As we all know the main objective behind separating interface from implementation is hiding implementation details in binary form. This is where you must separate the data structures and algorithms. Your template classes must represent only data structures not the algorithms. This enables you to hide more valuable implementation details in separate non-templatized class libraries, the classes inside which would work on the template classes or just use them to hold data. The template class would actually contain less code to assign, get and set data. Rest of the work would be done by the algorithm classes.
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.