C++ template class reference pass by-reference - c++

i was studying template classes andi have seen a tutorial code in a book.
There is a class named Stack as the following:
// Stack class template.
#ifndef STACK_H
#define STACK_H
template< typename T >
class Stack
{
public:
Stack( int = 10 ); // default constructor (stack size 10)
// destructor
~Stack()
{
delete [] stackPtr; // deallocate internal space for stack
} // end ~Stack destructor
bool push( const T& ); // push an element onto the stack
bool pop( T& ); // pop an element off the stack
// determine whether Stack is empty
bool isEmpty() const
{
return top == -1;
} // end function isEmpty
// determine whether Stack is full
bool isFull() const
{
return top == size - 1;
} // end function isFull
private:
int size; // # of elements in the stack
int top; // location of the top element (-1 means empty)
T *stackPtr; // pointer to internal representation of the stack
}; // end class template Stack
// constructor template
template< class T >
Stack< T >::Stack( int s )
: size( s > 0 ? s : 10 ), // validate size
top( -1 ), // Stack initially empty
stackPtr( new T[ size ] ) // allocate memory for elements
{
// empty body
} // end Stack constructor template
// push element onto stack;
// if successful, return true; otherwise, return false
template< class T >
bool Stack< T >::push( const T &pushValue )
{
if ( !isFull() )
{
stackPtr[ ++top ] = pushValue; // place item on Stack
return true; // push successful
} // end if
return false; // push unsuccessful
} // end function template push
// pop element off stack;
// if successful, return true; otherwise, return false
template< class T >
bool Stack< T >::pop( T &popValue )
{
if ( !isEmpty() )
{
popValue = stackPtr[ top-- ]; // remove item from Stack
return true; // pop successful
} // end if
return false; // pop unsuccessful
} // end function template pop
#endif
Also there is a main tester function that uses a function template as following.
// Fig. 14.4: fig14_04.cpp
// Stack class template test program. Function main uses a
// function template to manipulate objects of type Stack< T >.
#include <iostream>
#include <string>
#include "Stack.h" // Stack class template definition
using namespace std;
// function template to manipulate Stack< T >
template< typename T >
void testStack(
Stack< T > &theStack, // reference to Stack< T >
T value, // initial value to push
T increment, // increment for subsequent values
const string stackName ) // name of the Stack< T > object
{
cout << "\nPushing elements onto " << stackName << '\n';
// push element onto Stack
while ( theStack.push( value ) )
{
cout << value << ' ';
value += increment;
} // end while
cout << "\nStack is full. Cannot push " << value
<< "\n\nPopping elements from " << stackName << '\n';
// pop elements from Stack
while ( theStack.pop( value ) )
cout << value << ' ';
cout << "\nStack is empty. Cannot pop" << endl;
} // end function template testStack
int main()
{
Stack< double > doubleStack( 5 ); // size 5
Stack< int > intStack; // default size 10
testStack( doubleStack, 1.1, 1.1, "doubleStack" );
testStack( intStack, 1, 1, "intStack" );
system("pause");
} // end main
What could be reason usage of reference in testStack function?
When i make change denition as
Stack< T > theStack,
i get an error message that says "debug assertion failed" after program ends.

There is no copy constructor in Stack, so when you replace
Stack<T>&
to
Stack<T>
the default ctor is used.
The second copy is destroying already cleaned pointer.
delete[] stackPtr;

i think the best think is using reference when using a class's instance as a function parameter. But i just wanted to try copy constructor and added following code into Stack class and nothing changed. Error message appeared again with program end. What could be the correct copy constructor function?
// copy constructor template
template< typename T >
Stack< T >::Stack(const Stack &something)
{
top = something.top;
size = something.size;
stackPtr = something.stackPtr;
}

Related

why am i getting a clang: error: linker command failed with exit code 1 ( use -v to see invocation )

I am working on a class assignment, relatively new to the c++ language and I have tried to function the code to hopefully get rid of the error but, have not been successful. can anyone help me out?, I am primarily working with mathstack template class and calling it to push a number to the stack but the following code comes up.
error message : clang++-7 -pthread -std=c++17 -o main MathStack.cpp main.cpp
/tmp/main-69d6a9.o: in function 'menu(int&)'; main.cpp:(.text+0x297): undefined reference to
'MathStack<int>::push(int)'clang: error : linker command failed with code 1 (use -v to see
invocation)
**/ Implementation file for the MathStack class**
#include "MathStack.h"
#include <iostream>
//***********************************************
// Member function add. add pops *
// the first two values off the stack and *
// adds them. The sum is pushed onto the stack. *
//***********************************************
template <class T>
void MathStack<T>::add()
{
T num, sum;
// Pop the first two values off the stack.
pop(sum);
pop(num);
// Add the two values, store in sum.
sum += num;
// Push sum back onto the stack.
push(sum);
}
//***********************************************
// Member function sub. sub pops the *
// first two values off the stack. The *
// second value is subtracted from the *
// first value. The difference is pushed *
// onto the stack. *
//***********************************************
template <class T>
void MathStack<T>::sub()
{
T num, diff;
// Pop the first two values off the stack.
pop(diff);
pop(num);
// Subtract num from diff.
diff -= num;
// Push diff back onto the stack.
push(diff);
}
//**********************************************
// Member function mult. multiplies first two *
// values of the stack. *
//**********************************************
template <class T>
void MathStack<T>::mult()
{
T num, res;
// pop the first two values of the stack
pop(res);
pop(num);
// multiply thw two values
res = res*num;
// push result back into the stack
push(res);
}
template <class T>
//*********************************************
// Member funciton div. divides the first two *
// values of the stack. *
// shows an error when divided by zero *
//*********************************************
void MathStack<T>::div()
{
T quot, divisor;
// pop the first two values of the stack
pop(divisor);
pop(quot);
// exexption
if (divisor == 0)
{
cout << "ERROR: Cannot divide by zero.\n";
}
else {quot = quot/divisor; } // division formula
// push quotient back into the stack
push(quot);
}
//*************************************************
// Member function push pushes the argument onto *
// the stack. *
//*************************************************
template <class T>
void MathStack<T>::push(T num)
{
if (isFull())
{
cout << "The stack is full.\n";
}
else
{
top++;
stackArray[top] = num;
}
}
//****************************************************
// Member function pop pops the value at the top *
// of the stack off, and copies it into the variable *
// passed as an argument. *
//****************************************************
template <class T>
void MathStack<T>::pop(T &num)
{
if (isEmpty())
{
cout << "The stack is empty.\n";
}
else
{
num = stackArray[top];
top--;
}
}
//***************************************************
// Member function isFull returns true if the stack *
// is full, or false otherwise. *
//***************************************************
template <class T>
bool MathStack<T>::isFull() const
{
bool status;
if (top == stackSize - 1)
status = true;
else
status = false;
return status;
}
//****************************************************
// Member funciton isEmpty returns true if the stack *
// is empty, or false otherwise. *
//****************************************************
template <class T>
bool MathStack<T>::isEmpty() const
{
bool status;
if (top == -1)
status = true;
else
status = false;
return status;
}
// file specifies the stack class and use of math functions
#include <iostream>
#include "MathStack.h"
using namespace std;
// Constants for the menu choices
const int Add = 1,
Subtract = 2,
Multiply = 3,
Division = 4,
QUIT = 5;
// Function prototypes
void menu(int &);
void getStackSize(int &);
int main()
{
int stackSize; // The stack size
int choice; // To hold a menu choice
menu(choice);
// Create the stack.
MathStack<int> Math(stackSize);
MathStack<float> Math1(stackSize);
return 0;
}
//************************************************
// The menu function displays the menu and gets *
// the user's choice, which is assigned to the *
// reference parameter. *
//************************************************
void menu(int &choice)
{
int stackSize;
int number;
getStackSize(stackSize);
// Display the menu and get the user's choice.
cout << "\nWhat do you want to do?\n"
<< Add
<< " - Add items from the stack\n"
<< Subtract
<< " - Subtact items from the stack\n"
<< Multiply
<< " - Multiply items from the stack\n"
<< Division
<< " - Divide items form the stack\n"
<< QUIT
<< " - Quit the program\n"
<< "Enter your choice: ";
cin >> choice;
// Validate the choice
while (choice < Add || choice > QUIT)
{
cout << "Enter a valid choice: ";
cin >> choice;
}
switch(choice)
{
case 1:
MathStack<int> Math(stackSize);
for (int i = 0; i < stackSize; i++)
{
cout << " Enter number to insert to the stack:\n" << endl;
}
cin >> number;
Math.push(number);
}
}
//************************************************
// The getStackSize function gets the desired *
// stack size, which is assigned to the *
// reference parameter. *
//************************************************
void getStackSize(int &size)
{
// Get the desired stack size.
cout << "How big should I make the stack? ";
cin >> size;
// Validate the size.
while (size < 1)
{
cout << "Enter 1 or greater: ";
cin >> size;
}
}

Pop and push in stacks

I have a Data Structures assignment to use stacks for postfix algorithm. I think I'm nearly there but am struggling on a couple of things.
What do I put into the postfixstack.pop() arguments on Line 83 of cpp file?
How do I check if the stack is empty on Line 87 of cpp file?
I have 2 files, a .cpp and a .h file, both of them are below.
Thanks for any help.
using namespace std;
#include <iostream>
#include <stdlib.h>
#include <string>
#include "stack.h"
//Purpose of the program: **
//Algorithm: **
int main()
{
stack postfixstack; // integer stack
string expression; // user entered expression
cout << "type a postfix expression: " ;
cin >> expression;
int i = 0; // character position within expression
char item; // one char out of the expression
int box1; // receive things from pop
int box2; // receive things from pop
while (expression[i] != '\0')
{
try
{
item = expression[i]; // current char
// ** do all the steps in the algorithm given in Notes-1
if (item >= '0' && item <= '9') {
postfixstack.push(item);
}
else if (item == '+' || item == '-' || item == '*') {
if (item == '+') {
postfixstack.pop(box1);
postfixstack.pop(box2);
int tempResult = (box1 + box2);
postfixstack.push(tempResult);
}
if (item == '-') {
postfixstack.pop(box1);
postfixstack.pop(box2);
int tempResult = (box1 - box2);
postfixstack.push(tempResult);
}
if (item == '*') {
postfixstack.pop(box1);
postfixstack.pop(box2);
int tempResult = (box1 * box2);
postfixstack.push(tempResult);
}
}
else {
throw ;
}
} // this closes try
// Catch exceptions and report problems and quit the program now (exit(1)).
// Error messages describe what is wrong with the expression.
catch (stack::Overflow) {
{cerr << "Error: You have caused the stack to overflow." << endl; }
exit(1);
}
catch (stack::Underflow)
{cerr << "Error: You have caused the stack to underflow." << endl;
exit(1);
}
catch (char const* errormsg ) // for invalid item case
{cerr << "Error: You have entered an invalid item." << endl;
exit(1);
}
i++; // go back to the loop after incrementing i
}// end of while
// After the loop successfully completes:
// Pop the result and show it.
*postfixstack.pop();*
// If anything is left on the stack, an incomplete expression
// was found so inform the user.
if (*Need to check if stack is empty*) {
cerr << "Elements remain on the stack, incomplete expression error" << endl;
exit(1);
}
}// end of the program
****This is the beginning of the header file*****
// File type: header file stack.h
//=======================================================
//----- Globally setting up the aliases ----------------
const int MAX = 10; // The MAX number of elements for the stack
// MAX is unknown to the client
typedef int el_t; // the el_t type is char for now
// el_t is unknown to the client
//-------------------------------------------------------
class stack
{
private: // to be hidden from the client
el_t el[MAX]; // el is an array of el_t's
int top; // top is index to the top of stack
public: // available to the client
// Add exception handling classes here
class Overflow {}; // empty class – used as an exception name only
class Underflow {}; // empty class – used as an exception name only
// prototypes to be used by the client
// Note that no parameter variables are given
stack(); // constructor to create an object
~stack(); // destructor to destroy an object
// PURPOSE: if not full, enters an element at the top;
// otherwise throws an exception - Overflow
// PARAMETER: pass the element to be pushed
void push(el_t);
// PURPOSE: if not empty, removes and gives back the top element;
// otherwise throws an exception - Underflow
// PARAMETER: provide variable to receive the popped element (by ref)
void pop(el_t&);
// PURPOSE: if not empty, gives the top element without removing it;
// otherwise, throws an exception - Underflow
// PARAMETER: provide the top element of the stack (pass by reference)
void topElem(el_t&);
//PURPOSE: Determines if the stack is Empty. Returns true if stack is empty
bool isEmpty();
//PURPOSE: Determines if the stack is Full. Returns true if stack is full
bool isFull();
//PURPOSE: Displays all of the elements of the stack
void displayAll();
//PURPOSE: Clears all of the elements in the stack until it is empty
void clearIt();
};
The way you are implementing the stack as an array you can use the index (your top variable) to keep track of your stack's size as long as its use is well defined.
For instance, you can say that top is pointing to the next available place to put a new element so that an empty stack would have top == 0. This would solve the part for checking if an array is empty.
Following that same definition when you pop the stack you're removing the top element. If the datatype your stack is holding is a simple type you can just decrease the value of top by one.
void pop (el_t& val) //Perhaps return the value instead of return by reference
{
val= el[--top]; //Decrease top first because top is pointing to next EMPTY space.
}

Why does my stack object change a default value after being created?

So I have a stack created as below. The variable top is supposed to represent the current index, or the "top index". So by doing some testing, the constructor does get called and the value of top is -1 while the program is still running the constructor method. However, after creating the stack object, and testing to see what the value of top is, I keep getting top to be 32767. Literally, all that main does is create a new stack as
Stack s; //Testing while this is running to see value of top... I get -1
//Testing here to see value of top... I get 32767
-
The stack is created as shown below.
#ifndef __STACK_H_
#define __STACK_H_
class Stack{
int stackSize;
int top;
char* items;
public:
Stack();
~Stack();
void push(char c);
char pop();
bool isFull();
bool isEmpty();
};
#endif
And the implementation as below:
/* STACK IMPLEMENTATION FILE */
#include "stack.h"
#include <iostream>
using namespace std;
Stack::Stack(){
cout << "Ctor is run." << endl;
stackSize = 10; //Stack Size is 10
int top = -1; //Currently empty stack
cout << top << endl;
items = new char[stackSize];
}
Stack::~Stack(){ //Destructor
delete[] items;
}
void Stack::push(char c){ //Push next into stack
items[++top] = c;
cout << top << endl;
}
char Stack::pop(){ //Pop one from stack
return items[top--];
}
bool Stack::isFull(){ //Checks to see if stack is full
if (top + 1 == stackSize) return true;
}
bool Stack::isEmpty(){ //Checks to see if stack is empty
if (top == -1) return true;
}
You want top = 1 not int top = 1 in your constructor. The former assigns to the member, the latter initialises a local variable that goes out of scope at the end of the constructor.

C++ HW Help using stack

I am a little stuck on how to use the stack and why I would even use stack in the code I am writing. The assingment says to write a program that checks if the user input is well-Iformed or not. It is a simple prgram that has three different selections the use can choose from. 1. basic brackets () 2. standard brackets ()[]{} and 3. User-definded brackets. The only thing the main program is suppose to do is to check if the users input is well-formed or not and display only that message on the screen.
I have a StackLS.cpp and a Stack.h file I am using along with my main.cpp. I will paste a sample code below from each.
StackLS.h
typedef int elemType; // flexible data type
class StackLS
{
private:
// inner class node
class Node
{
public:
elemType data; // data portion
Node *next; // link to the seccessor
}; // end Node
// data members
Node *topItem; // pointer to the top element of this stack
// utilities
public:
// constructors
StackLS(void); // default constructor
StackLS(const StackLS& aStack); // copy constructor
// observers
bool isEmpty(void) const;
// returns true if this stack is empty
// false otherwise
bool isFull(void) const;
// returns true if this stack is full
// false otherwise
elemType top(void) const;
// precondition: this stack is not empty
// returns top element in this stack
// transformers
void push(const elemType& item);
// precondition: this stack is not full
// adds item to this stack
void pop(void);
// removes top element from this stack if exist
// remains empty otherwise
void makeEmpty(void);
// makes this stack empty
// destructor
~StackLS(void);
}; // end StackLS
StackLS.cpp
// constructors
StackLS::StackLS(void)
// default constructor
{
topItem = 0;
} // end default constructor
StackLS::StackLS(const StackLS& aStack)
// copy constructor
{
} // end copy constructor
// observers
bool StackLS::isEmpty(void) const
// returns true if this stack is empty
// false otherwise
{
return topItem == 0;
} // end isEmpty
bool StackLS::isFull(void) const
// returns true if this stack is full
// false otherwise
{
return false;
} // end isFull
elemType StackLS::top(void) const
// precondition: this stack is not empty
// returns top element in this stack
{
// return (*topItem).data;
return topItem->data;
} // end top
// transformers
void StackLS::push(const elemType& item)
// precondition: this stack is not full
// adds item to this stack
{
Node *newNode = new Node;
newNode->data = item;
newNode->next = topItem;
topItem = newNode;
} // end push
void StackLS::pop(void)
// removes top element from this stack if exist
// remains empty otherwise
{
if (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end pop
void StackLS::makeEmpty(void)
// makes this stack empty
{
while (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end makeEmpty
// destructor
StackLS::~StackLS(void)
{
//while (!isEmpty())
// pop();
while (topItem != 0)
{
Node *temp = topItem;
topItem = topItem->next;
delete temp;
}
} // end destructor
Here is the main.cpp that I have so far.
main.cpp
#include <iostream>
#include <string>
#include "StackLS.h"
using namespace std;
do {
int main()
{
char answer;
char n;
StackLS stack;
cout << " ********** MENU ********** " << endl;
cout << " 1. Basic Brackets () " << endl;
cout << " 2. Standard Brackets ()[]{} " << endl;
cout << " 3. User-Defined brackets " << endl;
cout << " Please enter your choice: " << endl;
switch (choice){
case 1:
cout << "Current Setting: () " << endl;
cout << "Enter your expression followed by a ; : " << endl;
do {
cin >> answer;
while (answer != ;)
}
} // end main
}
while (choice != 'n' || 'N')
Again I am wondering how I would use the stack I have shown you in this program (main.cpp). I am a little confused on why I would use stack and why. Any help is appreciated. Thanks. The main.cpp may not be right but again I am learning and that is why I am here to learn more. Thanks
When you see an opening brace, you push it onto the stack. When you see a closing brace, you make sure it is the counterpart of the brace on top of the stack, then pop it off. When your input is done, you make sure the stack is empty.

C++ Stack Implementation

Hey all! Having a little trouble with my stack. Im trying to print each element that I've pushed onto the stack.
Starting with the stack ctor we know that we have a fixed size for the array. So I allocate the items struct object to hold just that much space:
stack::stack(int capacity)
{
items = new item[capacity];
if ( items == NULL ) {
throw "Cannot Allocoate Sufficient Memmory";
exit(1);
}
maxSize = capacity;
top = -1;
}
Yes, items is a struct type of the object "item". Have a look:
class stack
{
stack(int capacity);
~stack(void);
...
private:
int maxSize; // is for the item stack
int top; // is the top of the stack
struct item {
int n;
};
item *items;
public:
friend ostream& operator<<(ostream& out, stack& q)
...
First and formost we want to add to the stack by pushing each incoming element into the array FILO:
bool stack::pushFront( const int n )
{
if ( top >= maxSize-1 )
{
throw "Stack Full On Push";
return false;
}
else
{
++top;
items[top].n = n;
}
return true;
}
// just a textbook example here:
stack::~stack(void)
{
delete [] items;
items = NULL;
maxSize = 0;
top = -1;
}
Yes the real issue for me is the items[++top].n = n; statement. I've been trying to find out how I can drag (+) the items array out to see ALL of the array elements after I push onto the stack.
Im wondering why I cant drag that items[++top].n = n statement out when im debugging. All that comes up is the value that is passed as an 'n' paramater. Do I need to use a stack object type array to store the values into?
When I overload the << operator and try to print the elements I get an insanely large negative number:
ostream& operator<<(ostream& out, stack& q)
{
if ( q.top <= 0 ) // bad check for empty or full node
out << endl << "stack: empty" << endl << endl;
else
for ( int x = 0; x < q.maxSize; x++ )
{
out << q.items[x].n; // try to print elements
}
return out;
}
I'm way off and I need some guidence if anyone has the time!
In the overloaded << operator in the for loop you are iterating maxsize times. But you might not have pushed maxsize elements into the stack. You should iterate top times. Also, write a default constructor for item structure and initialize all the variblaes so that you do not get garbage values when you try to print them.
When printing the stack, you should only go up to top, not up to maxSize.