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.
Related
Let us have an abstract template class Stack which will inherit realisation from second class parameter in template.
// file Stack.h
template <class T, template<typename> class Implementation>
class Stack : private Implementation<T>
{
public:
Stack() {}
virtual ~Stack() {}
void push(const T& x) { Implementation<T>::push(x); }
void pop() { Implementation<T>::pop(); }
const T& top() { return Implementation<T>::top(); }
bool empty() const { return Implementation<T>::empty(); }
};
Then, we have a class that will provide implementation and then be used in instantiating a template.
// file ListStack.h
template <class Elem>
class ListStack
{
private:
size_t _size;
struct ListNode
{
Elem _elem;
ListNode * _next;
};
ListNode * _top;
~ListStack();
friend class Stack<Elem, ListStack>;
public:
ListStack();
bool empty() const;
const Elem& top() const;
void pop();
void push(const Elem & value);
size_t size() const;
};
I declared destructor private and made Stack class a friend class so it can be only used when instantiating Stack class.
// file main.cpp
#include "Stack.h"
#include "ListStack.h"
int main()
{
// ListStack<int> list; cannot instaniate
Stack<int, ListStack> s;
}
The question is why ListStack.h don't need to include Stack.h file?
In order for template code to be compiled, it needs to be called somewhere. In your case, you have two header files both defining what a template should be. The call to the template is being made in a file that includes both Stack and ListStack. Since you are creating the Stack variable in main.cpp, you can get away with List and ListStack not knowing each other in the header files.
I suspect that the Stack class will be defined in your main.cpp by the compiler but I'm not sure if I'm right about it.
As for the ListStack class instantiation error, that's because your destructor is private. Check this LINK for more details.
EDIT: You also need to create definitions for your ListStack class. Without that, nothing will work. I assumed for simplicity that you have empty definitions everywhere.
I am trying to implement a generic Linked list in C++ and I get an error that I don't know how to deal with.
Here is my Link class implementation (which is also generic):
#ifndef LINK_H
#define LINK_H
#include <iostream>
#include "typeinfo.h"
#include "LinkedList.h"
template <class T>
class Link
{
public:
//|-------------------- Constructors --------------------
Link(T data): m_data(data), next(NULL){}
//|-------------------- Methods --------------------
T getData(){
return m_data;
}
T& getNext(){
return next;
}
void setNext(Link* newLink){
next = newLink;
}
void setData(T data){
m_data = data;
}
//|-------------------- Operator overload --------------------
bool operator==(Link& other){
if(this->m_data == other.m_data)
return true;
return false;
}
void operator++(){
this = this->next;
}
//|-------------------- Friend functions --------------------
friend std::ostream& operator<<(std::ostream& out,const Link<T>& link){
out<<link.m_data;
return out;
}
//|-------------------- Destructor --------------------
virtual ~Link(){}
protected:
private:
//|-------------------- Private fields --------------------
T m_data;
Link<T>* next;
friend class LinkedList<T>
};
#endif // LINK_H
As you can see I am trying to let LinkedList<T> be a friend of Link<T> so I can get access to
its fields (I want them to stay private).
Now, I think its relevant to post all of my LinkedList<T> implementation because its a lot of code, but here's how I defined the class:
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "List.h"
#include "Link.h"
template <class T>
class LinkedList : public List<T>
{
public:
and here are the fields:
private:
//|-------------------- Private fields --------------------
Link<T>* head;
Now, I get this error:
error: 'LinkedList' is not a class template
I have tried to search the error and found this.
But it does not seem to be the problem in my implementation.
I also found this.
But I could not understand how to implement this forward declaration in my case (or why I even need it).
I'd really appreciate clarification here.
Thanks in advance
Simply add a forward declaration of LinkedList before the definition of the Link class like this:
template<typename U>
class LinkedList;
// Now the definition as you have it above...
template <class T>
class Link
{
public:
...
See here.
BTW, you're missing a ; after your friend declaration in your first code block.
I declared a node class in my main.cpp but when I try to use the node when declaring functions in my header file it does not recognize the node data type.
template<class E> class doublyLinkedList;
class doublyLinkedList
{
public:
doublyLinkedList();
~doublyLinkedList();
bool IsEmpty() const;
const T& front() const; // return front node
const T& back() const; //returning rear node
void addToFront(const T& e); // add to front
void addToBack(const T& e); //adds to end
void removeFront(); // remove front node
void removeBack(); //remove rear node
private:
DNode<T>* header; // sentinel node front of node
DNode<T>* trailer; //sentinel node for back of node
protected:
void add(DNode* v, const Element& e); // insert new node before v
void remove(DNode* v); // remove node v
};
template<class E> class doublyLinkedList; //forward declaration
template <class E>
class DNode{
private:
E element; //node's actual value
DNode<E>* head;
DNode<E>* tail;
template<class T> friend class doublyLinkedList;
};
Typically, classes will be declared in header files to prevent the very problem that you are seeing. Nothing prevents a class/struct being declared locally in a body file (cpp) file however.
If you would like a class to be visible to another class then it must be either fully declared or forward declared.
class foo; // forward declaration
class bar {
bar(foo& r):ref(r){};
foo & ref; // Ok because of the forward declaration
foo* ptr; // Ok
//foo full; // Not legal as the full declaration is needed.
};
class foo{ // declaration of class
// members and methods
};
class third{
bar b; // Ok, full declaration is available;
};
Let's suppose your class is MyNode, your function is MyFunc(MyNode), the header file is foo.h, and you have a source file bar.cpp. (This is one reason you should give examples in your questions; if you don't, then other people get to name your things.)
Naturally bar.cpp contains this line:
#include "foo.h"
When the compiler tries to compile bar.cpp, it encounters the declaration MyFunc(MyNode X), and complains "what the heck is a MyNode? I quit!"
The simplest way to solve this is to put the definition of MyNode in foo.h, above the declaration of the function that uses it.
The best way is to put a line in foo.c:
class MyNode;
above any other mention of MyNode. (This tells the compiler "there's a class named MyNode, don't worry what it is, it will be provided later.) And somehow (e.g. with an #include statement) put the the definition of MyNode above any code that actually uses it.
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
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.