Below is the code for stack along with one or two extra options. Kindly let me know if there are any concerns/critical issues. Below are the two link for previous versions.
//*************Version 1.2: Begineer's Implementation of Stack ***************//
#include <iostream>
#include <fstream>
template <class T>
class Mystack
{
private:
T *input;
int top;
int capacity;
public:
Mystack();
Mystack(const Mystack<T> &source);
Mystack<T> & operator=(const Mystack<T> &source);
~Mystack();
void push(T const& x);
void pop();
T& topElement() const;
bool isEmpty() const;
void print(std::ostream &os) const;
};
template <class T>
Mystack<T>::Mystack() //default copy constructor
{
top = -1;
capacity = 5;
input = new T[capacity];
}
template <class T>
Mystack<T>::Mystack(const Mystack<T> &source) // copy constructor
{
input = new T[source.capacity];
top = source.top;
capacity = source.capacity;
for (int i = 0; i <= source.top; i++)
{
input[i] = source.input[i];
}
}
template <class T>
Mystack<T> & Mystack<T>::operator=(const Mystack<T> &source) // assignment operator overload
{
input = new T[source.capacity];
top = source.top;
capacity = source.capacity;
for (int i = 0; i <= source.top; i++)
{
input[i] = source.input[i];
}
return *this;
}
template <class T>
Mystack<T>::~Mystack() // destructor
{
delete[] input;
}
template <class T>
void Mystack<T>::push(T const& x) //Passing x by Const Reference
{ // Valus of x cannot be changed now in the function!
if (top + 1 == capacity)
{
T *vec = new T[capacity * 2];
for (int i = 0; i <= top; i++)
{
vec[i] = std::move(input[i]);
}
delete[]input; // Avoiding Memory Leak.
input = vec;
capacity *= capacity;
}
input[++top] = x;
}
template <class T>
void Mystack<T>::pop() //pop the element from the top of stack
{
if (isEmpty())
{
throw std::out_of_range("Stack Underflow");
}
else
{
std::cout << "The popped element is" << input[top--];
}
}
template <class T>
bool Mystack<T>::isEmpty() const //const: none of the class members can be modified in this function
{
if (top == -1)
{
std::cout << "Is Empty" << std::endl;
return true;
}
else
{
std::cout << "Not Empty" << std::endl;
return false;
}
}
template <class T>
T& Mystack<T>::topElement() const // returns top element of the stack
{
if (top == -1)
{
throw std::out_of_range("No Element to Display");
}
else
{
std::cout << "The top element is : " << input[top];
return input[top];
}
}
template <class T>
void Mystack<T>::print(std::ostream &os) const //a more of a general print function, can be used to write to a file
{
for (int i = 0; i <= top; i++)
{
os << input[i] << " ";
}
}
int main()
{
Mystack<int> intstack, inttemp;
Mystack<float> floatstack, floattemp;
Mystack <int> temp(intstack);
Mystack<char> charstack, chartemp;
int choice;
std::ofstream some_file("testfile.txt"); // creation of file
int int_elem;
float float_elem;
char char_elem;
std::cout << "Enter the type of stack" << std::endl;
std::cout << "1. int ";
std::cout << "2. float ";
std::cout << "3. Char" << std::endl;
std::cin >> choice;
if (choice == 1)
{
int ch = 1;
while (ch > 0)
{
std::cout << "\n1. Push ";
std::cout << "2. Top ";
std::cout << "3. IsEmpty ";
std::cout << "4. Pop ";
std::cout << "5. Stack content to File";
std::cout << "6. Copy Constrcutor";
std::cout << "7. Assignemnt Operator";
std::cout << "8. Print ";
std::cout << "9. Exit" << std::endl;
std::cout << "Enter the choice" << std::endl;
std::cin >> ch;
switch (ch)
{
case 1:
std::cout << "Enter the number to be pushed" << std::endl;
std::cin >> int_elem;
intstack.push(int_elem);
break;
case 2:
std::cout << "Get the TOP Element" << std::endl;
try
{
intstack.topElement();
}
catch (std::out_of_range &oor)
{
std::cerr << "Out of Range error:" << oor.what() << std::endl;
}
break;
case 3:
std::cout << "Check Empty" << std::endl;
intstack.isEmpty();
break;
case 4:
std::cout << "POP the element" << std::endl;
try
{
intstack.pop();
}
catch (const std::out_of_range &oor)
{
std::cerr << "Out of Range error: " << oor.what() << '\n';
}
break;
case 5:
std::cout << "Stack data to file" << std::endl;
intstack.print(some_file); //printing data to a file
break;
case 6:
{
Mystack<int> s4(intstack); // copy constructor called
s4.print(std::cout);
break;
}
case 7:
inttemp = intstack; // assignment operator overload
inttemp.print(std::cout);
break;
case 8:
intstack.print(std::cout);
break;
case 9:
exit(0);
default:
std::cout << "Enter a valid input" << std::endl;
break;
}
}
}
else if (choice == 2)
{
int ch = 1;
while (ch > 0)
{
std::cout << "\n1. Push ";
std::cout << "2. Top ";
std::cout << "3. IsEmpty ";
std::cout << "4. Pop ";
std::cout << "5. Write Data to a file";
std::cout << "6. Copy Constrcutor Use";
std::cout << "7. Assignemnt Operator Use";
std::cout << "8. Print ";
std::cout << "9. Exit" << std::endl;
std::cout << "Enter the choice" << std::endl;
std::cin >> ch;
switch (ch)
{
case 1:
std::cout << "Enter the number to be pushed" << std::endl;
std::cin >> float_elem;
floatstack.push(float_elem);
break;
case 2:
std::cout << "Get the TOP Element" << std::endl;
try
{
floatstack.topElement();
}
catch (std::out_of_range &oor)
{
std::cerr << "Out of Range error:" << oor.what() << std::endl;
}
break;
case 3:
std::cout << "Check Empty" << std::endl;
floatstack.isEmpty();
break;
case 4:
std::cout << "POP the element" << std::endl;
try
{
floatstack.pop();
}
catch (const std::out_of_range &oor)
{
std::cerr << "Out of Range error: " << oor.what() << '\n';
}
break;
case 5:
std::cout << "Stack data to file" << std::endl;
floatstack.print(some_file); //data to file
break;
case 6:
{
Mystack<float> s5 = floatstack; // copy constructor called
s5.print(std::cout);
break;
}
case 7:
floattemp = floatstack; // assignment operator overload
floattemp.print(std::cout);
break;
case 8:
floatstack.print(std::cout);
break;
case 9:
exit(0);
default:
std::cout << "Enter a valid input" << std::endl;
break;
}
}
}
else if (choice == 3)
{
int ch = 1;
while (ch > 0)
{
std::cout << "\n1. Push ";
std::cout << "2. Top ";
std::cout << "3. IsEmpty ";
std::cout << "4. Pop ";
std::cout << "5. Write Data to a file";
std::cout << "6. Copy Constrcutor Use";
std::cout << "7. Assignemnt Operator Use";
std::cout << "8. Print ";
std::cout << "9. Exit" << std::endl;
std::cout << "Enter the choice" << std::endl;
std::cin >> ch;
switch (ch)
{
case 1:
std::cout << "Enter the number to be pushed" << std::endl;
std::cin >> char_elem;
charstack.push(char_elem);
break;
case 2:
std::cout << "Get the TOP Element" << std::endl;
try
{
charstack.topElement();
}
catch (std::out_of_range &oor)
{
std::cerr << "Out of Range error:" << oor.what() << std::endl;
}
break;
case 3:
std::cout << "Check Empty" << std::endl;
charstack.isEmpty();
break;
case 4:
std::cout << "POP the element" << std::endl;
try
{
charstack.pop();
}
catch (const std::out_of_range &oor)
{
std::cerr << "Out of Range error: " << oor.what() << '\n';
}
break;
case 5:
std::cout << "Stack data to file" << std::endl;
charstack.print(some_file);
break;
case 6:
{
Mystack<char> s6 = charstack; // copy constructor called
s6.print(std::cout);
break;
}
case 7:
chartemp = charstack;
chartemp.print(std::cout);
break;
case 8:
charstack.print(std::cout);
break;
case 9:
exit(0);
default:
std::cout << "Enter a valid input" << std::endl;
break;
}
}
}
else
std::cout << "Invalid Choice";
std::cin.get();
}