Sorted Linked List in C++ - c++

Here is my problem.
I have a Linked List class as follows:
#include <iostream>
#include "List.h"
template <class Elem>
class LList : public List<Elem> { //List is a virtual base class
protected:
Node <Elem> *head;
Node <Elem> *fence;
Node <Elem> *tail;
int leftCount;
int rightCount;
void init();
void removeAll();
public:
LList();
~LList();
//Rest of methods overridden from List class
//////
};
Then I have a class called SortedLList which inherits from LList as follows:
#include "LinkedList.h"
#include "Helper.h"
template <class Elem>
class SortedLList : public LList<Elem> {
protected:
Helper *helper;
public:
SortedLList();
~SortedLList();
bool insert(const Elem&); //Override insertion method from LList class
};
In the implementation of SortedLList (SortledLList.cpp):
#include "SortedLList.h"
template <class Elem>
SortedLList<Elem>::~SortedLList() {
removeAll();
}
template <class Elem>
bool SortedLList<Elem>::insert(const Elem &_e) {
fence = head;
//Rest of Code..
}
I am having a compiler error that says : Use of undeclared identifier removeAll(). Same thing for fence and head pointers are not being recognized. What did I do wrong?
Thank You.

Because your class is a template there are certain issues that can happen to confuse the compiler. You may think your code is straight forward and easy to understand, and in this case it is. Older compilers used to do their best to guess and compile this code.
However, newer compilers are more strict and fail on all versions of this type of code, in order to prevent programmers from relying on it.
What you need to do is use the this pointer when calling base class functions. That makes the call unambiguous and clear. That would look like this->removeAll().
Another option would be to use a full name qualification like LList<Elem>::removeAll(). I prefer using this because it is easier to read.

Related

Preventing redefinition issue in case of separating the declaration and definition of template class

The question is that in case of stencil out a class via templates, then include it to use as usual: It'll be gotten the error explained in below:
If it is demanded to use struct Something straightforwardly within Node.inl. It needs to include "Node.h" header as follows, but this will comes with some troubles. We violate the rule of one definition, but the template class needs to include their definitions in the same file as they are declared. Otherwise, the compiler will forget to stencil out the member functions upon the instance created. As a result, we can not use these functions via the instance initialized. So how do we manage that while we want to preserve the separateness of declarations and definitions, persist not violate one definition rule?
Node.inl:
#include "Node.h"
void foo(){
struct Something s{1, 2};
}
template <class T>
Node<T>::Node(int data, Node<T> *next) : m_data{data}, m_next{next} {}
template <class T>
void Node<T>::setData(int data) {
m_data = data;
}
template <class T>
int Node<T>::getData() const {
return m_data;
}
template <class T>
void Node<T>::setNext(Node<T> *next) {
m_next = next;
}
template <class T>
Node<T> * Node<T>::getNext() const {
return m_next;
}
template <class T>
void Node<T>::allocMemoryNext() {
m_next = new Node<T>();
}
Node.h:
#ifndef THE1_NODE_H
#define THE1_NODE_H
struct Something{
int x;
int y;
};
template <class T>
class Node {
private:
T m_data;
Node *m_next;
public:
explicit Node(int data = 0, Node *next = nullptr);
void setData(int data);
[[nodiscard]] int getData() const;
void setNext(Node *next);
[[nodiscard]] Node *getNext() const;
void allocMemoryNext();
};
#include "Node.inl"
#endif //THE1_NODE_H
we want to preserve the separateness of declarations and definitions
There is no such "separateness" as far as templates are concerned. In order for anyone to use them, they must be defined. And Node.h provides those definitions.
Node.inl is part of Node.h. You have logically separated the text into different files, but they aren't separate as far as any practical reality is concerned. Every user of Node.h should be getting Node.inl's stuff too, which is why you #include "Node.inl" at the end of the file. Nobody but Node.h should be including Node.inl, so there is no reason for Node.inl to #include "Node.h".
So there is no problem, once you remove the needless include of a thing that is definitely already there.

Inheritance issue?

So i am trying to create a stack class that inherits member functions from a linked list class. The linked list class has no actual implementation of its own; it's essentially an abstract virtual class. Both are template classes. When I try to access a member function using my derived stack class, I am receiving a "no member function declared in class 'Stack'" error. Below is my code. I'm not sure what the issue is. I have included the names of the .h files as well as the : public List sequence in the declaration of the stack class. Please help! If any more code is required for you to answer this question please let me know!! Thank you!
Code for declaration of List parent class
#ifndef LIST221_H
#define LIST221_H
#include "Node221.h"
template <typename T>
class List221 {
public:
List221();
~List221();
virtual int size() const;
virtual bool empty() const;
virtual bool push(T obj); //will push in a new node
virtual bool pop(); //will pop off the top node
virtual bool clear();
protected:
private:
Node<T>* front;
Node<T>* rear;
};
#endif
Code for declaration of Stack class.
Includes List.h file
#include "List221.h"
#include "Node221.h"
template <typename T>
class Stack221 : public List221 <T> {
public:
Stack221();
~Stack221();
T top();
private:
Node<T>* topnode;
};
Example of Member function from List class that I am trying to access.
Also includes List.h at top of page
template <typename T>
bool Stack221<T>::push(T obj) {
Node<T>* o = new Node(obj);
if (topnode == nullptr) {
topnode = o;
}
else {
o->next = topnode;
topnode = o;
}
return true;
}
Error being displayed
error: no ‘bool Stack221<T>::push(T)’ member function declared
in class ‘Stack221<T>’
bool Stack221<T>::push(T obj) {
^
It seems that you have provided an implementation of Stack221<T>::push, but you have not declared that method in your class declaration.

C++ declaring multiple classes in one header

I got an assignment where I am supposed to create a Linked list by using CRTP. I got some starting code/suggestion on how to define the classes in their respective header files. I have omitted some code below:
Link.h
#include <iosfwd>
template<class T>
class List;
template<class T>
class Link {
Link* next;
friend class List<T>;
public:
Link();
virtual ~Link() = default;
//etc...
List.h
#include "Link.h"
template<class T>
class List : public Link<T> {
public:
List();
T* First();
T* Last();
//Etc...
This code compiles without any errors. Now my question is about the two first lines in Link.h, template<class T> class List;. I experimented a little bit and realized that Link.h won't compile without that class definition beacuse of the friend class List<T> statement. But why can't I just write #include "List.h" and remove the inheritance inside List.h and just use that definition from the start? I have tried this of course and get the error
"error: 'List' is not a class template
friend class List<T>;"
it would look like this:
Link.h
#include <iosfwd>
#include "List.h"
template<class T>
class Link {
Link* next;
friend class List<T>;
public:
Link();
virtual ~Link() = default;
List.h
#include "Link.h"
template<class T>
class List {
public:
List();
T* First();
Try to use a unique template in one file only or in files that build upon each other sequentially, not equally. In your case, you should probably move all of your files to one. Your .h files seem to mirror each other, so your compiler would have go back and forth between your references, but they do so in order. Choose the order of precedence.

Defining a Nested Class From Header File

Still fairly new with C++ and trying to kick it up a notch here. I would like to build a Heap class, with a nested Node class, and add a heap sort aspect to the Heap class. I have done something similar with Java, but I am getting stuck trying to define the nested class in the .cpp file.
#pragma once
#ifndef HEAP_H
#define HEAP_H
template <class T>
class Heap
{
public:
class Node
{
public:
Node(T);
T data;
private:
Node *parent;
Node *left_child;
Node *right_child;
boolean is_root;
};
Heap(T*, int);
sort_it();
private:
T *unsorted_list
Node root;
void build_heap();
void add_node(Node);
void swap_root();
void trickle_down();
void heap_sort();
};
#endif
Now when I go to define my nested class in the .cpp file I cannot simply...
#include "stdafx.h"
#include "Heap.h"
#include <iostream>
//Defining Heap Constructor
Heap::Heap(T* incoming_array, int _size)
{
unsorted_list = incoming_array;
size = _size;
}
//Defining Node Constructor
Heap::Node(T _data)
{
data = _data;
left_child = right_child = parent = Null;
is_root = false;
}
I am not sure if my problem is how I am incorporating the template, or if my syntax for defining the inner class is wrong. Both Generic Programming and Nested Classes are unfamiliar to me in C++
If you use any generic type in nested class you have to specify the template.
template<class T>
class Node
To define the template class constructor outside the class,
template<typename T>
Node<T>::Node(T _data)
Declare the member as follows,
Node<T> root

My class (container of pointers to another class) cannot seem to access the public constructor

I am struggling to create a QList of pointers to objects of a self-made class, in this case Node. I have tried to use the same method as in the Library example of An Introduction to Design Patterns in C++ with Qt, Ezust and Ezust.
For some reason, the container class NodeList cannot access the constructor in the Node class and complains that it is private, even though it is public.
I have tried using the friend keyword in the definition of Node, but that did not work either. I cannot see where the problem is coming from, as I am referencing the pointers in exactly the same way as the working example from the textbook.
#ifndef NODE_H
#define NODE_H
#include <QString>
#include <QList>
class Node
{
public:
Node() {}
void setNodeLabel(QString label);
QString getNodeLabel();
Node(QString label);
private:
QString nodeLabel;
};
class NodeList : public QList<Node*>
{
public:
NodeList() {}
~NodeList();
void addNode(Node*& node);
private:
NodeList(const NodeList&);
NodeList& operator=(const NodeList&);
};
#endif // NODE_H
The error I get when trying to compile this is as follows:
\qlist.h:106: error: 'struct QList<Node*>::Node' is private
struct Node { void *v;
^
\node.h:25: error: within this context
void addNode(Node*& node);
^
NodeList derives from QList<Node*>, which has a nested class named Node, which is in the private section of QList. When you use the unqualified type Node anywhere in NodeList, that name resolves to QList<Node*>::Node. Hence, you get that error.
Unless you intend to add more functionality to NodeList, you can use:
using NodeList = QList<Node*>;
and get rid of the class NodeList.