C++ LinkedList using template - c++

I want to make my own linkedlist implementatin in c++ using templates. However, I run into several compiler errors. Here is the code:
template <class T>
class Node{
T datum;
Node _next = NULL;
public:
Node(T datum)
{
this->datum = datum;
}
void setNext(Node next)
{
_next = next;
}
Node getNext()
{
return _next;
}
T getDatum()
{
return datum;
}
};
template <class T>
class LinkedList{
Node<T> *node;
Node<T> *currPtr;
Node<T> *next_pointer;
int size;
public:
LinkedList(T datum)
{
node = new Node<T>(datum);
currPtr = node; //assignment between two pointers.
size = 1;
}
void add(T datum)
{
Node<T> *temp = new Node<T>(datum);
(*currPtr).setNext((*temp));
currPtr = temp;
size++;
}
T next()
{
next_pointer = node;
T data = (*next_pointer).getDatum();
next_pointer = (*next_pointer).getNext();
return data;
}
int getSize()
{
return size;
}
};
when I try to instantiate this class, I got the following errors:
LinkedList.cpp: In instantiation of `Node<int>':
LinkedList.cpp:35: instantiated from `LinkedList<T>::LinkedList(T) [with T = int]'
LinkedList.cpp:60: instantiated from here
LinkedList.cpp:7: error: `Node<T>::_next' has incomplete type
LinkedList.cpp:5: error: declaration of `class Node<int>'
make[2]: *** [build/Debug/Cygwin-Windows/LinkedList.o] Error 1
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
I'm using NetBeans IDE. Could anybody give me some suggestion to improve it? Thanks a lot!!

Just like when you do Node<T> *node; in the LinkedList, you need to also do the same in your Node class
template <class T>
class Node{
T datum;
Node<T> *_next;//template parameter
//also, need to make this a pointer and initialized in constructor
public:
//...
void setNext(Node<T> next) //template parameter
{
_next = next;
}
Node<T> getNext() //template parameter
{
return _next;
}
//...
};

Besides the syntax being wrong:
class Node{
T datum;
Node _next = NULL;
//....
you can't have a member of the same type as a member. You can use a pointer though:
template <class T>
class Node{
T datum;
Node<T>* _next;
and set it in the constructor (because =NULL wouldn't be legal there).
Related: Why is a class allowed to have a static member of itself, but not a non-static member?

Your Node class should contain a pointer to the next Node, not a Node directly. Here you've a recursive type which is impossible to handle for the compiler.
Another mistake is that you cannot initialize a member like this. You must do that in the constructor.
So, replace Node _next = NULL; by Node *_next; and initialize the pointer _next to nullptr in your constructor.

It might just be this line:
Node _next = NULL;
You really need that to be a pointer (Node<T>* _next). If a class contained an instance of its own type, then THAT instance would have its own instance of that type and so on ad memorum exhaustum.

Related

How to construct an class template with std::allocator construct

How can i construct my class template in my member function newNode (in std=++98) without new operator ?
I tried to put an constructor of Node or the variable key but it doesn't work .
template <class T>
class Node{
public:
Node(){
_left = NULL;
_right = NULL;
_height = 0;
};
Node(const Node &ref);
Node &operator=(const Node &ref);
~Node(){};
T _key;
Node *_left;
Node *_right;
int _height;
};
template <class T, class A = std::allocator<Node<T> > >
class Tree{
public:
[...]
//attribut
Node<T> *head;
A _alloc;
Node<T> *newNode(T key){
Node<T> *node = _alloc.allocate(sizeof(Node<T>));
_alloc.construct(node, ???);
return (node);
}
};
What can i put in my 2nd argument of construct ?
allocate() already calculates the memory required for objects, you shouldn't use sizeof there. Also, don't use construct(), it was removed in C++20. Use placement new instead:
Node<T> *newNode(T key){
Node<T> *node = _alloc.allocate(1); // allocate 1 * sizeof(Node<T>)
new(node) Node<T>(/*arguments to Node<T> constructor, but Node<T> only has default constructor, so nothing goes here*/);
return node;
}
With C++20, you can also use std::construct_at(), which has easier syntax than placement new:
Node<T> *newNode(T key){
Node<T> *node = _alloc.allocate(1); // allocate 1 * sizeof(Node<T>)
node = std::construct_at(node);
return node;
}
To use construct() before C++11, you need to create an object to be copied:
Node<T> *newNode(T key){
Node<T> *node = _alloc.allocate(1); // allocate 1 * sizeof(Node<T>)
_alloc.construct(node, Node<T>());
return node;
}

Calling a default constuctor for a stack using linked list getting error C2760

okay running into a block when it comes to inner class default constructors. in this assignment I have to make a stack utilizing linked list, I got the functions all set I am just having trouble trying to properly set a default constructor for the inner class StackNode at least that is what the compiler is telling me.
class StackNode { // this is given in the assignment its not the full .h
public:
StackNode(const DataType& nodeData, StackNode* nextPtr)
{
dataItem = nodeData;
next = nextPtr;
}
DataType dataItem;
StackNode* next;
};
StackNode* top;
};
// here is my default constructor for the class
template <typename DataType>
StackLinked<DataType>::StackLinked(int maxNumber)// <--this part is given inside is what i have done.
{
top = NULL;
StackNode::StackNode(const DataType x = NULL; StackNode * y = nullptr)
{
this->dataItem = x;
this->next = y;
}
//if i remove this i get error C2512 no appropriate default constructor for the StackNode<DataType>::StackNode
}
I haven't found a thread yet to help me so I posted this in hopes of finding out what I am missing.
update 1 -
error in output
(file dest)\StackLinked.cpp(11,23): error C2760: syntax error: unexpected token 'const', expected ')'
test6.cpp
(file dest)\StackLinked.cpp(11,23): error C2760: syntax error: unexpected token 'const', expected ')'
this is the error given when I try to Build my code
You are trying to define the body of the StackNode constructor inside the body definition of the StackLinked constructor. That will not work. They need to be defined separately. But you already have a definition for the StackNode constructor inline in the declaration of the StackNode class, so there is no need to define a 2nd body for that constructor.
template <typename DataType>
class StackLinked
{
private:
class StackNode {
public:
StackNode(const DataType& nodeData, StackNode* nextPtr)
{
dataItem = nodeData;
next = nextPtr;
}
DataType dataItem;
StackNode* next;
};
StackNode* top;
public:
StackLinked(int maxNumber);
};
...
template <typename DataType>
StackLinked<DataType>::StackLinked(int maxNumber)
{
top = NULL;
}
Otherwise, don't make the StackNode constructor definition be inline, just like you are not for the StackLinked constructor:
template <typename DataType>
class StackLinked
{
private:
class StackNode {
public:
StackNode(const DataType& nodeData, StackNode* nextPtr);
DataType dataItem;
StackNode* next;
};
StackNode* top;
public:
StackLinked(int maxNumber);
};
...
template <typename DataType>
StackLinked<DataType>::StackLinked(int maxNumber)
{
top = NULL;
}
template <typename DataType>
StackLinked<DataType>::StackNode::StackNode(const DataType& nodeData, StackNode* nextPtr)
{
dataItem = nodeData;
next = nextPtr;
}

Errors when using Object Template for Linked List in C++

I'm trying to make a double linked list of objects in c++. So far I have a Node and DLinkedList class and they worked with integers, but when I tried to convert the type from int to object using the template I'm getting errors. I tried researching but I can't find a good example that uses a header and implementation file with the object template. Can someone help me out?
Here's my header file Node.h:
template <typename Object>
class Node {
public:
Node(const Object &data, Node next, Node prev);
Node(const Object &data);
const Object& getData();
Node* getNext();
Node* getPrev();
void setData(const Object &data);
void setNext(Node *next);
void setPrev(Node *prev);
private:
Object data;
Node *next;
Node *prev;
};
#endif
And this is my Node.cpp file:
template <typename Object>
Node<Object>::Node(const Object &data, Node next, Node prev){
this->data = data;
this->next = &next;
this->prev = &prev;
}
Node<Object>::Node(const Object &data){
this->data = data;
this->prev = nullptr;
this->next = nullptr;
}
const Object& Node<Object>::getData(){
return this->data;
}
Node* Node<Object>::getNext(){
return this->next;
}
Node* Node<Object>::getPrev(){
return this->prev;
}
void Node<Object>::setData(const Object &data){
this->data = data;
}
void Node<Object>::setNext(Node *next){
this->next = next;
}
void Node<Object>::setPrev(Node *prev){
this->prev = prev;
}
These are the first few errors I'm getting:
Node.cpp:24:6: error: use of undeclared identifier 'Object'
Node<Object>::Node(const Object &data){
^
Node.cpp:24:26: error: unknown type name 'Object'
Node<Object>::Node(const Object &data){
^
Node.cpp:24:15: error: extra qualification on member 'Node'
Node<Object>::Node(const Object &data){
~~^
Node.cpp:25:2: error: invalid use of 'this' outside of a non-static member
function
this->data = data;
^
The rest of the errors are similar for the rest of the code. I don't understand why it's not recognizing Object when I defined it in the template. Any advice on how to fix this mess is appreciated!

how to return a pointer to template class from a function?

#ifndef __linkedListH__
#define __linkedListH__
template<class T>
class Node
{
public:
T data;
Node *next;
};
template<class T>
class linkedList
{
public:
Node<T> *head;
linkedList();
Node<T>* returnHead();
Node<T>* Insert(Node *head,T data);
};
template<class T>
linkedList<T>::linkedList()
{
head = NULL;
}
Node* linkedList<T>::returnHead()
{
return head;
}
Node* linledList<T>::Insert(Node *head,int data)
{
Node *newNode = new Node();
newNode->data = data;
newNode->next = NULL;
if(!head)
return newNode;
Node *temp = head;
while(temp->next)
{temp=temp->next;}
temp->next = newNode;
return head;
}
#endif
In this implementation of a linked list, Pls help me with the declaration of "returnHead" and "Insert" method. When I call these methods from main function, I'm getting the following errors with declaration of both methods:
1.ISO C++ forbids declaration of 'Node' with no type
2.expected ';' before '*' token
You're missing a few template <class T> and <T> components:
template <class T>
Node<T>* linkedList<T>::returnHead()
{
return head;
}
template <class T>
Node<T>* linledList<T>::Insert(Node<T> *head,int data)
{
Node<T> *newNode = new Node<T>();
newNode->data = data;
newNode->next = NULL;
if(!head)
return newNode;
Node<T> *temp = head;
while(temp->next)
{temp=temp->next;}
temp->next = newNode;
return head;
}
This need to repeat the template declaration header before each member function is one of the reasons why member functions of class templates are often implemented inline in the class right where they're declared.
Also, I believe the parameter data should be of type T, and not int. It doesn't make much sense otherwise.
As an additional note, you might want to give your Node class template a constructor (taking next and data), so that you don't have to initialise it from outside.
Unrelated issue: names which contain two consecutive underscores (or ones which start with an underscore followed by an uppercase letter) are reserved for the compiler & standard library; using them for your own things is illegal. Rename the include guard suitably.

Linked List not compiling

This code is not compiling in my system; I'm using Eclipse.
// Linked list head
template<class T>
struct Node
{
// constructor
Node(const T& a) : pNext(NULL), data(a) {}
Node* pNext; //link
T data;
}; // end of header
// List code
#include <iostream>
#include "LinkedList.h"
template<class T>
class linkedList
{
public:
typedef Node<T> Node;
//constructor creates empty list
linkedList() : pHead(NULL), size(0) {}
~linkedList()
{
Node* pIter = pHead;
while(pIter != NULL)
{
Node* pNext = pIter->pNext;
delete pIter;
pIter = pNext;
}
}
void insert(const T& data)
{
Node* pInsert = new Node(data);
if(pHead == NULL)
{
pHead = pInsert;
}
else
{
pInsert->pNext = pHead;
pHead = pInsert;
}
}
private:
Node* pHead; // always points to head of list
unsigned int size; // stores number of elements in list
};
Here is the error message:
./LinkedList.cpp:14:18: error: declaration of 'typedef struct Node<T> linkedList<T>::Node'
../LinkedList.h:4:1: error: changes meaning of 'Node' from 'struct Node<T>'
make: *** [LinkedList.o] Error 1
The error is fairly clear: Don't reuse the name Node. Instead you can write something like this:
typedef Node<T> node_type;
Template names and type names share the same namespace in C++, so you cannot use the same name for two distinct entities, even though one is a template and the other a type.
(Somewhat tangentially, there is a fair amount of subtlety surrounding tag names both in C and C++; this article may be worth a read, and this and this.)