Academic Integrity: tutoring, explanations, and feedback — we don’t complete graded work or submit on a student’s behalf.

I am recieving errors when trying to run a program using the following C++ templ

ID: 3673546 • Letter: I

Question

I am recieving errors when trying to run a program using the following C++ templated doubly linked list. I believe the error is with my constructor. Everything works fine in my version that is not templated. Can someone show me how to correct these errors? Thanks!

#include <cstdlib>

#include <iostream>

using namespace std;

template <class T>

class DoublyLinkedList; // class declaration

// list node

template <class T>

class DListNode {

private: T obj;

DListNode *prev, *next;

friend class DoublyLinkedList<T>;

public:

DListNode(T e=0, DListNode *p = NULL, DListNode *n = NULL)

: obj(e), prev(p), next(n) {}

T getElem() const { return obj; }

DListNode * getNext() const { return next; }

DListNode * getPrev() const { return prev; }

};

// doubly linked list

template <class T>

class DoublyLinkedList {

protected: DListNode<T> header, trailer;

public:

DoublyLinkedList() : header(0), trailer(0){} // constructor

//{ header.next = &trailer; trailer.prev = &header; }

  

DoublyLinkedList(const DoublyLinkedList& dll)

{

// Initialize the list

//header.next = &trailer; trailer.prev = &header;

  

  

DListNode<T> *current = dll.getFirst();

  

while(current != dll.getAfterLast())

{

  

this->insertLast(current->getElem());

current = current->getNext(); //iterate

}

  

}// copy constructor

  

~DoublyLinkedList()

{

DListNode<T> *prev_node, *node = header.next;

while (node != &trailer) {

prev_node = node;

node = node->next;

delete prev_node;

}

header.next = &trailer;

trailer.prev = &header;

} // destructor

  

DoublyLinkedList& operator=(const DoublyLinkedList& dll)

{

// Delete the whole list

/* Complete this function */

  

DListNode<T> *prev_node, *node = header.next;

while (node != &trailer)

{

prev_node = node;

node = node->next;

delete prev_node;

}

header.next = &trailer;

trailer.prev = &header;

  

  

  

// Copy from dll

/* Complete this function */

  

  

DListNode<T> *current = dll.getFirst();

  

while(current != dll.getAfterLast())

{

  

this->insertLast(current->getElem());

current = current->getNext(); //iterate

}

  

  

return *this;

} // assignment operator

  

// return the pointer to the first node

DListNode<T> *getFirst() const { return header.next; }

// return the pointer to the trailer

const DListNode<T> *getAfterLast() const { return &trailer; }

// return if the list is empty

bool isEmpty() const { return header.next == &trailer; }

T first() const

{

if (isEmpty())

throw EmptyDLinkedListException("Empty Doubly Linked List");

return header.next->obj;

}// return the first object

  

T last() const

{

if (isEmpty())

throw EmptyDLinkedListException("Empty Doubly Linked List");

return trailer.prev->obj;

} // return the last object

void insertFirst(T newobj)

{

DListNode<T> *newNode = new DListNode<T>(newobj, &header, header.next);

header.next->prev = newNode;

header.next = newNode;

} // insert to the first of the list

  

  

struct EmptyDLinkedListException : std::range_error {

explicit EmptyDLinkedListException(char const* msg=NULL): range_error(msg) {}

};

  

T removeFirst()

{

if (isEmpty())

throw EmptyDLinkedListException("Empty Doubly Linked List");

DListNode<T> *node = header.next;

node->next->prev = &header;

header.next = node->next;

T obj = node->obj;

delete node;

return obj;

} // remove the first node

void insertLast(T newobj)

{

DListNode<T> *newNode = new DListNode<T>(newobj, trailer.prev,&trailer);

trailer.prev->next = newNode;

trailer.prev = newNode;

} // insert to the last of the list

  

  

T removeLast()

{

if (isEmpty())

throw EmptyDLinkedListException("Empty Doubly Linked List");

DListNode<T> *node = trailer.prev;

node->prev->next = &trailer;

trailer.prev = node->prev;

T obj = node->obj;

delete node;

return obj;

}// remove the last node

};

// return the list length

template <class T>

int DoublyLinkedListLength(DoublyLinkedList<T>& dll) {

DListNode<T> *current = dll.getFirst();

int count = 0;

while(current != dll.getAfterLast()) {

count++;

current = current->getNext(); //iterate

}

return count;

}

// output operator

template <class T>

ostream& operator<<(ostream& out, const DoublyLinkedList<T>& dll)

{

  

/* Complete this function */

  

  

const DListNode<T> *temp;

temp=dll.getFirst();

  

while(temp != NULL)

{

out<<temp->getElem()<<" ";

temp=temp->getNext();

}

  

return out;

}// extend range_error from <stdexcept>

Explanation / Answer

Since the definition of the constructor is not inline in the class definition, the compiler does not make it implicitly inline. Now, if you include the same file in multiple translation units (i.e. *.cppfiles), the linker will produce exactly the error you see, because each of the *.cpp files will contain its own definition of the constructor without them being marked as inline functions.

The solution is easy, just put a inline in front of the constructor declaration:

Alternatively, if the function body is short, as is the case with the constructor shown above, directly inline the function definition into the class definition.

Hire Me For All Your Tutoring Needs
Integrity-first tutoring: clear explanations, guidance, and feedback.
Drop an Email at
drjack9650@gmail.com
Chat Now And Get Quote