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.
Related
I have
template <class T>
class arrList: public linearList<T> {
public:
arrList() {}
arrList(const arrList<T>& List);
~arrList() {delete[] element; }
protected:
void indexCheck(int indx) const;
T* element;
int arrLength;
int listSize;
};
And the copy constructor is
template<class T>
inline arrList<T>::arrList(const arrList<T>& List) {
element = List.element;
arrLength = List.arrLength;
listSize = List.listSize;
}
But im not sure if this is correct for T* element, and also if I have to insert the void function in the copy constructor too.
I am new to this, and I don't know a lot about it, so any kind of help will be appreciated.
Currently working on an implementation of a stack controlled by a resizable array. Trying to instantiate a new object of ResizableArrayStack gives errors.
E0322 object of abstract class type "csc232::ResizableArrayStack" is not allowed: ResizableArrayStack.cpp 107
function "csc232::ResizableArrayStack::isEmpty [with ItemType=int]" is a pure virtual function
function "csc232::ResizableArrayStack::push [with ItemType=int]" is a pure virtual function
function "csc232::ResizableArrayStack::pop [with ItemType=int]" is a pure virtual function
function "csc232::ResizableArrayStack::peek [with ItemType=int]" is a pure virtual function
StackInterface.h
#include "pch.h"
#pragma once
#ifndef CSC232_HW05_RESIZABLE_ARRAY_STACK_STACK_INTERFACE_H
#define CSC232_HW05_RESIZABLE_ARRAY_STACK_STACK_INTERFACE_H
namespace csc232 {
template<typename ItemType>
class StackInterface {
public:
/**
* Sees whether the stack is empty.
* #return True if the stack is empty, or false if not.
*/
virtual bool isEmpty() const = 0;
/**
* Adds a new entry to the top of this stack.
* #param newEntry The object to be added as a new entry.
* #return True if the addition is successful or false if not.
* #post If the operation was successful, newEntry is at the top of the stack.
*/
virtual bool push(const ItemType &newEntry) = 0;
/**
* Removes the top of this stack.
* #return True if the removal was successful or false if not.
* #post If the operation was successful, the top of the stack has been removed.
*/
virtual bool pop() = 0;
/**
* Returns a copy of the top of this stack.
* #return A copy of the top the stack.
* #post A copy of the top of the stack has been returned, and the stack is unchanged.
*/
virtual ItemType peek() const = 0;
/**
* Destroys this stack and frees its assigned memory
*/
virtual ~StackInterface() = default;
};
}
#endif //CSC232_HW05_RESIZABLE_ARRAY_STACK_STACK_INTERFACE_H
ResizableArrayStack.h
#include "pch.h"
#pragma once
#ifndef CSC232_HW05_RESIZABLE_ARRAY_STACK_RESIZABLE_ARRAY_STACK_H
#define CSC232_HW05_RESIZABLE_ARRAY_STACK_RESIZABLE_ARRAY_STACK_H
#include "StackInterface.h"
namespace csc232 {
template <typename ItemType>
class ResizableArrayStack : public StackInterface<ItemType> {
private:
ItemType* items;
int top, capacity, count;
static const int DEFAULT_CAPACITY = 10;
public:
ResizableArrayStack();
ResizableArrayStack(int initial_capacity);
ResizableArrayStack(const ResizableArrayStack &rhs);
ResizableArrayStack(ResizableArrayStack &&rhs) = delete;
void operator=(const ResizableArrayStack<ItemType> &rhs);
void operator=(ResizableArrayStack &&rhs) = delete;
~ResizableArrayStack();
bool isEmpty() const = 0;
bool push(const ItemType &newEntry) = 0;
bool pop() = 0;
ItemType peek() const = 0;
int getCapacity() const;
private:
void init();
void increase_size();
};
#endif // CSC232_HW05_RESIZABLE_ARRAY_STACK_RESIZABLE_ARRAY_STACK_H
ResizableArrayStack.cpp
#include "pch.h"
#include <iostream>
#include "ResizableArrayStack.h"
template<typename ItemType>
csc232::ResizableArrayStack<ItemType>::ResizableArrayStack() : count(0), capacity(DEFAULT_CAPACITY) {
init();
}
template<typename ItemType>
csc232::ResizableArrayStack<ItemType>::ResizableArrayStack(int initial_capacity) : count(0), capacity(initial_capacity) {
init();
}
template<typename ItemType>
void csc232::ResizableArrayStack<ItemType>::init() {
items = new ItemType[capacity];
count = 0;
}
template<typename ItemType>
csc232::ResizableArrayStack<ItemType>::ResizableArrayStack(const ResizableArrayStack &rhs) {
*this = rhs;
}
template<typename ItemType>
void csc232::ResizableArrayStack<ItemType>::operator=(const ResizableArrayStack<ItemType> &rhs) {
if (this != rhs)
{
delete[] items;
init();
for (int i = 0; i < rhs.count; i++)
{
this->push(rhs.items[i]);
}
}
}
template<typename ItemType>
csc232::ResizableArrayStack<ItemType>::~ResizableArrayStack() {
delete[] items;
}
template<typename ItemType>
bool csc232::ResizableArrayStack<ItemType>::isEmpty() const {
return count == 0;
}
template<typename ItemType>
bool csc232::ResizableArrayStack<ItemType>::push(const ItemType &newEntry) {
if (count == capacity)
increase_size();
items[count] = newEntry;
return false;
}
template<typename ItemType>
bool csc232::ResizableArrayStack<ItemType>::pop() {
if (count == 0)
throw std::underflow_error("Underflow exception.");
count--;
return false;
}
template<typename ItemType>
ItemType csc232::ResizableArrayStack<ItemType>::peek() const {
top = capacity - 1;
return items[top];
}
template<typename ItemType>
int csc232::ResizableArrayStack<ItemType>::getCapacity() const {
return capacity;
}
template<typename ItemType>
void csc232::ResizableArrayStack<ItemType>::increase_size() {
capacity = capacity * 2;
ItemType *temp = new ItemType[capacity];
for (int i = 0; i < capacity; i++)
temp[i] = items[i];
delete[] items;
items = temp;
}
int main(int argc, char* argv[]) {
csc232::ResizableArrayStack<int> stack;
}
In your ResizableArrayStack class definition your virtual function overrides are still "pure":
bool isEmpty() const = 0;
bool push(const ItemType &newEntry) = 0;
bool pop() = 0;
ItemType peek() const = 0;
remove the = 0 and for good measure, tell the compiler that these are overrides:
bool isEmpty() const override;
bool push(const ItemType &newEntry) override;
bool pop() override;
ItemType peek() const override;
A class is abstract if the final overrider of any virtual function is pure virtual. Your definition of template class ResizableArrayStack has = 0; at the ends of several virtual function overrides. This means they are considered pure virtual even though they also have definitions. (Defining a pure virtual function is valid C++, and the definitions could be called using a qualified name, but still must be overridden by something else to get a non-abstract class.)
Just take the = 0 pieces out of ResizableArrayStack.
But note also, you normally should not put definitions with template parameters in a *.cpp file: See the Q&A "Why can templates only be implemented in the header file?"
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;
I have an interface ICollection implementing a collection ArdalanCollection like this:
template <typename T>
class ICollection
{
public:
virtual void add(T*) = 0;
virtual T* get(int) = 0;
virtual int count() = 0;
};
template <typename T>
class ArdalanCollection :public ICollection<T>
{
public:
ArdalanCollection() {
index = 0;
};
virtual void add(T* obj) {
encapsolateImplementation.insert(make_pair(index++, obj));
};
virtual T* get(int index) {
return encapsolateImplementation[index];
};
virtual int count() {
return encapsolateImplementation.size();
};
private:
int index;
unordered_map < int, T* > encapsolateImplementation;
};
what I want is to have a generic iterator in ICollection interface which can loop all over the internal container elements(I haven't decided to choose unordered_map as my internal container I might change it to boost or something else). I want to use it in this way:
Node *node1 = new Node(1, 0, 0, 0);
Node *node2 = new Node(1, 0, 0, 0);
ICollection<Node> *nodes = new ArdalanCollection<Node>();
nodes->add(node1);
nodes->add(node2);
for (it=nodes->iterator.begin(); it < nodes->iterator.end(); it++) {
}
First your for loop idiom is not correct. It should rather look like
for(auto it = nodes->begin(); it != nodes->end(); it++)
then something along:
template <typename T, typename MyMap>
class ICollection
{
public:
typedef typename MyMap<int, T *>::iterator iterator;
virtual void add(T*) = 0;
virtual T* get(int) = 0;
virtual int count() = 0;
};
should be fine.
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.