Using variables from parent class - c++

I've been trying to use template to implement stack. And my question is how do I use the variables from the parent class in this situation?
In this case my compile error is: 'top, a, size' was not declared in this scope.
template<class T>
class buffer
{
public:
T *a;
int top,i,size;
};
template<class T>
class Queue: public buffer<T>
{
public:
Queue(int siz)
{
a=new T[siz];
size=siz;
top=-1;
}
void push(T ele)
{
if(top!=size-1){a[++top]=ele;}
}
T pop()
{
return(a[top--]);
}
void print()
{
for(i=0;i<top;i++)
cout<<" "<<a[i];
cout<<endl;
}
};

To make them dependent name, you have to use this-> or buffer<T>:: before.
so
this->a = new T[siz];
this->size = siz;
this->top = -1;

Related

How to use template for implementing STACK using LINKEDLIST in cpp

So i am trying to create a c++ file which implements stack and all its functions(push,pop,getTop,etc). I want to use Template so that i can make this Stack class for multiple datatypes. I am using linked list to store the data. Here is some example of stack i have implemented using linked list.
#include<iostream>
using namespace std;
template <class T>
class Node{
public:
T data;
Node *next;
Node()
{
next = NULL;
}
};
class Stack
{
Node *top;
public:
Stack();
int isEmpty();
int isFull();
void push(T data);
T pop();
void display();
};
Stack :: Stack()
{
top = NULL;
}
int Stack :: isEmpty()
{
if(top == NULL)
{
return 1;
}
else
{
return 0;
}
}
int Stack :: isFull()
{
int temp;
Node *t = new Node;
if(t==NULL)
{
temp = 1;
}
else
{
temp = 0;
}
delete t;
return temp;
}
void Stack :: push(T data)
{
Node *n;
if(isFull())
{
cout<<"\nStack overflow";
}
else
{
n = new Node;
n->data = data;
n->next = top;
top = n;
}
}
int Stack :: pop()
{
Node *t;
T temp;
if(isEmpty())
{
return temp;
}
else
{
t = top;
top = top->next;
temp = t->data;
delete t;
return temp;
}
}
void Stack :: display()
{
Node *p = top;
while(p != NULL)
{
cout<<"\n"<<p->data;
p = p->next;
}
}
So this is a preview of what i am trying to do, but i don't want to create different node and stack class for different data types. How can i achieve that using Templates. I tried it myself but i am getting lots of error and cant seem to understand why.
Thanks.
I suggest making the Node into an inner class of Stack. There's no need for users to be able to see it.
#include<iostream>
#include<utility>
template<class T>
class Stack {
struct Node { // inner class
T data;
Node *next;
};
Node* top = nullptr;
size_t m_size = 0;
public:
Stack() = default;
// rule of five - no copying, only moving allowed
Stack(const Stack&) = delete;
Stack(Stack&& rhs) noexcept :
top(std::exchange(rhs.top, nullptr)), m_size(rhs.m_size)
{}
Stack& operator=(const Stack&) = delete;
Stack& operator=(Stack&& rhs) noexcept {
std::swap(top, rhs.top);
m_size = rhs.m_size;
return *this;
}
~Stack() {
while(top) {
delete std::exchange(top, top->next);
}
}
bool empty() const { return m_size == 0; }
size_t size() const { return m_size; }
void push(const T& data) {
top = new Node{data, top};
++m_size;
}
T pop() {
T rv = std::move(top->data);
delete std::exchange(top, top->next);
--m_size;
return rv;
}
};
Demo
You can implement like bellow:
#include<iostream>
using namespace std;
template <typename Type>
class Node
{
public:
Type data;
Node<Type> *next;
};
template <typename Type>
class Stack
{
public:
Node<Type> *top;
void push(Type data);
Type pop();
};
int main()
{
}
Implementing a stack with a linked list requires simply storing a linked list privately, and constraining it with the stack's interface. The constraining is the key. The template parameter is the type you are storing in your stack.
The simplest* way is to take the time implement a linked list well, so that you only have to worry about constraining it in your stack class and not writing a linked list to behave like a stack in your stack class. The principle at play here is called Separation of Concerns.
Here's a quick example using std::list for simplicity's sake:
template <typename T>
class Stack {
public:
Stack() = default;
Stack(T val) : m_stack(val) {}
void push(T val) { m_stack.push_front(val); }
T& top() { return m_stack.front(); }
void pop() {
if (!m_stack.empty()) m_stack.pop_front();
}
bool empty() const { return m_stack.empty(); }
private:
std::list<T> m_stack{};
};
The if statement might not be necessary in the pop() function if you want the exception to be thrown in your stack.
Here's a main() that tests the stack:
int main() {
Stack<int> s1;
for (int i = 1; i < 11; ++i) s1.push(i);
while (!s1.empty()) {
std::cout << s1.top() << ' ';
s1.pop();
}
std::cout << '\n';
Stack<char> s2('A');
for (char l = 'B'; l != 'K'; ++l) s2.push(l);
while (!s2.empty()) {
std::cout << s2.top() << ' ';
s2.pop();
}
std::cout << '\n';
}
My only includes are <iostream> and <list>. The output:
10 9 8 7 6 5 4 3 2 1
J I H G F E D C B
I am able to avoid a lot of unnecessary work like the Rule of 5 because std::list handles it all for me. So I am fine with compiler-provided copy and move constructors and the destructor.
* This is much easier said than done. I keep a simple linked list around for those specific questions, and it is still ~130 lines of code, and does not have all the functionality necessary to be properly constrained to behave like a stack like I demonstrate with std::list.
If you've written a linked list already, the stack should be very simple as successfully writing a linked list requires demonstrating an extremely wide range of C++ knowledge and programming principles.

C++ private variable scoping rules

Here is the interface
template <class Type>
class stackADT
{
public:
virtual void initializeStack() = 0;
virtual bool isEmptyStack() const = 0;
virtual bool isFullStack() const = 0;
virtual void push(const Type& newItem) = 0;
virtual Type top() const = 0;
virtual void pop() = 0;
virtual void reverseStack(stackType<Type>& otherStack) = 0;
private:
int maxStackSize;
int stackTop;
Type *list;
};
Here is the reverse stack method which is part of class stackType which extends stackADT
template <class Type>
class stackType : public stackADT<Type>
{
private:
int maxStackSize;
int stackTop;
Type *list;
public:
/***
Other methods ...
**/
void reverseStack(stackType<Type>& otherStack)
{
int count = 0;
otherStack.list = new Type[maxStackSize]; // why does this WORK!!! its private
otherStack.stackTop = 0; // why does this WORK!!! its private
//copy otherStack into this stack.
for (int j = stackTop - 1; j >= 0; j--)
{
otherStack.push(list[j]);
count++;
}
}
Here is the main loop with the calls.
stackType<int> stack1(50);
stackType<int> stack2(50);
stack1.initializeStack();
stack1.push(1);
stack1.push(2);
stack1.push(3);
stack1.push(4);
stack1.push(5);
stack1.reverseStack(stack2);
So what's going on with this in C++ cause in Java, PHP, Python(mangled naming) and other OOD would not allow this.
I guess you are confused what private actually does because this would also work in Java.
Private means that instances of other classes (or no classes, meaning functions) can't change/call/invoke/... that member/method. The important part here is that it says other classes. Instances of the same class can change/call/invoke/... private members/methods.
As shown, it wouldn’t compile.
The point is that the function reverseStack is supposed to be a member method instead, so it should start with:
void stackADT::reverseStack(stackType<Type>& otherStack)
As a member method, it has access to private variables.

function of class Y is not a member of X, but class X is a friend of Y

There is a similar question to this with the function being an operator overload with arguments and that is the main emphasis, which is only confusing me further.
I am simply trying to execute a short recursive function on a tree class that gets called on non-empty Node objects in order to traverse down the tree's child nodes respectively.
My class declarations are as such:
template<class T>
class BTNode {
template<class I>
friend class BST;
T data;
BTNode<T>* left_;
BTNode<T>* right_;
...
}
template<class I>
class BST {
BTNode<I>* root_;
BTNode<I>* curr_;
BTNode<I>* parent_;
int currSize = 0;
public:
size_t size() const {
if (root_ == NULL) {
return currSize;
}
else {
BTNode<I>* left_ = root_->getLeft();
BTNode<I>* right_ = root_->getRight();
if (left_ != NULL)
currSize += left_->size();
if (right_ != NULL)
currSize += right_->size();
}
return currSize;
}
...
};
The error as it stands is:
'size()': is not a member of 'BTNode<I>'
So far, I have tried make BTNode a friend class of BST, and the error still prevails (having both classes become friends of each other).
Thanks in advance.
You misunderstand what friend declarations do. Saying that A is a friend of B means that A gains access to protected and private members of B. It allows A to call private functions of B, for example. It does not extend the interface of A or B in any way.
If I understand correctly what you're trying to achieve, you should be able to do that by having size take a parameter:
template<class I>
class BST {
BTNode<I>* root_;
BTNode<I>* curr_;
BTNode<I>* parent_;
public:
size_t size() const {
return size_(root_);
}
private:
static size_t size_(const BTNode<I> *node) {
if (node == NULL) {
return 0;
}
else {
return 1 + size_(node->getLeft()) + size_(node->getRight());
}
}
...
};

Classes misunderstanding and bad_alloc error or bad initialization?

I am trying to read some values remember them in object dep, and then show them. It shows random values and crashes. Can you tell me what is wrong in my program, it shoul be something about allocation..
#include<iostream>
)
{
std::cout<
and those are Wagon.h and Stack.h
template <typename T>
class Stack
{
T *stackArray;
....
Stack();
~Stack();
void push( T x );
void show();
void add(int M);
};
template <typename T>
Stack<T>::Stack()
{
stackArray = NULL;
topLevel = 0;
}
template <typename T>
Stack<T>::~Stack()
{
if ( stackArray != NULL )
delete [] stackArray;
}
void Wagon::printId()
{
std::cout<<id<<" ";
}
and main:
dep.addVagL(0,9);
dep.showDepot(2,2);
You can begin fixing your code by allocating the lines array in the Depot constructor:
Depot::Depot(int N, int M)
{
lines = new Stack<Wagon>[N];
for (int i=0; i<N; i++)
{
lines[i].add(M);
}
}

how to make a list of template abstract class

I must to do a list of template abstract base classes (and I have the delivered classes too)
but I don't can inizialize the element of my list because the element is an abstract class...
this is my declaration:
/* fsm (list node) declaration */
template<class step_type> class fsm {
protected:
step_type step;
step_type step_old;
step_type step_tmp;
char name[256];
fsm *next;
fsm *prev;
public:
fsm(step_type step);
virtual void update() = 0;
void show(){cout << step << ' ' << step_tmp << '\n'; };
void init(step_type st_current) {step = st_current;};
//metodi per gestione nodo lista
step_type getStep() { return step; }
fsm* getNext() { return next; }
fsm* getPrev() { return prev; }
void setStep(step_type s) { step = s; }
void setNext(fsm *n) { next = n; }
void setPrev(fsm *p) { prev = p; }
};
/* fsm_List declaration */
template <class step_type>
class fsm_List
{
fsm<step_type> *head, *tail;
int size;
public:
fsm_List();
fsm<step_type>* getHead() { return head; }
fsm<step_type>* getTail() { return tail; }
int getSize() { return size; }
void insert(fsm<step_type> *n); // add node to list
void insert(step_type &value); // new node and add in list
fsm<step_type> *search(step_type &value); //first node with value
void delnode(fsm<step_type> *n); // remove node
int delvalue(step_type &value); // remove all nodes
};
this is my delivered class:
class deri_pinza : public fsm<pin_steps>{
private:
bool cmd_prelevamento_done;
public:
deri_pinza(): fsm<pin_steps>(ST_PIN_BOOT){
cmd_prelevamento_done = false;
};
void update();
};
where:
enum pin_steps {
ST_PIN_BOOT,
ST_PIN_CHECK_MOTORE,
ST_PIN_ZERO_MOTORE,
ST_PIN_WAIT_ZERO_MOTORE,
ST_PIN_OPEN,
ST_PIN_READY,
};
I have tryed to test in my main, but it's wrong...
fsm<pin_steps> *one, *two, *three, *four, *five;
one = new fsm<pin_steps>(ST_PIN_CHECK_MOTORE);
two = new fsm<pin_steps>(ST_PIN_ZERO_MOTORE);
three = new fsm<pin_steps>(ST_PIN_WAIT_ZERO_MOTORE);
four = new fsm<pin_steps>(ST_PIN_OPEN);
five = new fsm<pin_steps>(ST_PIN_READY);
fsm_List<pin_steps> *mylist = new fsm_List<pin_steps>();
(*mylist)+=(*one);
(*mylist)+=(*two);
mylist->insert(one);
mylist->insert(two);
cout << *mylist << endl;
how can I inizialize the List without inizialize fsm ( abstract class)?
you can't create an instance of fsm<> with new, since it's abstract - it contains the pure virtual method virtual void update()=0;
you can for example:
fsm<pin_steps> *one...
one = new deri_pinza;
this is legal - and go on from here...
EDIT - followup to our comments:
if you need a more general deri pinza (a generic one), it can be defined as:
template <typename STEP_TYPE>
class deri_pinza_gen : public fsm<STEP_TYPE> {
private:
bool cmd_prelevamento_done;
public:
deri_pinza_gen(STEP_TYPE step) : fsm<STEP_TYPE>(step){
cmd_prelevamento_done = false;
};
virtual void update();
virtual ~deri_pinza_gen();
};
and then:
mylist->insert( new deri_pinza_gen<pin_steps>(ST_PIN_BOOT) );
mylist->insert( new deri_pinza_gen<pin_steps>(ST_PIN_CHECK_MOTORE) );
ANOTHER_list->insert( new deri_pinza_gen<ANOTHER_pin_steps>(ANTHER_enum_item) );
...
are valid insertions. I have declared update() virtual here, so you can derive your deri_pinza from this one, if you need it.