#include <iostream>
#include "stack.h"
usingnamespace std;
int main(void)
{
Stack<char> Char10; // Test Character Stack, Default constructor
Stack<float> Float5(5); // Test Float Stack
Stack<double> Double8(8); // Test Double Stack
Stack<bool> Bool2(2); // Test Bool Stack
Stack<char> Charcy(Char10); // Default copy constructor
Bool2.Push(true); // Test Push on Bool
Bool2.Push(false); // Test Push on Bool
Bool2.Push(true); // Test error on Push
cout << "Size of Bool2 is: " << Bool2.Size() << endl;
cout << "Top element of Bool2 is: " << Bool2.Top() << endl;
cout << "Size on Double8 should be 8: " << Double8.Size() << endl;
Char10.Push('A');
Char10.Push('B');
Char10.Push('C');
cout << "Test Pop on Char10, should produce a 'C': ";
Char10.Pop();
Char10.Push('C');
cout << "Test ostream overload on Charcy, should be Empty: ";
cout << Charcy << endl;
cout << "Test ostream overload on Char10, should be a 'C': ";
cout << Char10 << endl;
cout << "Test ostream overload on Char10, should be a 'B': ";
cout << Char10 << endl;
cout << "Test ostream overload on Char10, should be a 'A': ";
cout << Char10 << endl;
cout << "Test ostream overload on Char10, should be an error: ";
cout << Char10 << endl;
return 0;
}
pop of a stack usually gets the value and provides it to the user. yours discards the value.
what is your output?
while char* has a << magic overload, its the C string one and expects a 0 terminated string, which your stacks are not. Your overload will not behave well for non char*, even if you fix that. But you can see if the problem clears up with push (0) added in there to ensure the c-string compatibility.
pop of a stack usually gets the value and provides it to the user. yours discards the value.
The way that ChesterPlus does it is the same way that pop() works for std::stack in the standard library. The only difference is that std::stack::pop() returns void and the behaviour is undefined if you call it on an empty stack.
Though, you probably want to remove this line. It's meaningless and won't compile if the stack contains a type that is not implicitly convertible to int.
ChesterPlus wrote:
cout << Char10 << endl;
You repeat this code four times and expect different output each time, why?
The << operator does not modify the object that you print so it should print the same each time.
This is not correct. You're printing s._stack which is a pointer.
For non-char pointers this will print the memory address.
But as jonnin said, the << overload for char* is special so it will assume it's a pointer to the first character in a null-terminated array (s._stack is not a null terminated array so the behaviour is undefined).
If you want it to print all the element of the stack then you need to use a loop that loops over all the elements in the stack and outputs them one by one.
you are correct -- the stl pop does force you to get & then remove explicitly. Guess that was a throwback ... way back when you did your own containers, the ones I used pop gave the value back and I got used to it being a 2-for operation. Apologies, yours is fine if you get rid of the assignment to a discarded value.
Hi, ChesterPlus.
If I’m not misunderstanding your code, you’re using _top to represent the ‘size’ concept and you don’t tell properly apart the ‘size’ from the ‘capacity’.
‘Capacity’ → how many elements your array can store (before asking for new memory);
‘Size’ → the current number of elements that have been pushed into your array.
I don’t think you need _top at all.
constexprint Default_Size { 100 };
template <class T> class Stack {
public:
Stack()
: _capacity { Default_Size }
, _stack { new T[_capacity] }
, _size {}
{
}
private:
int _capacity; // The memory allocated
T* _stack;
int _size; // The number of elements the stack currently holds
T dummy; // ??? Do your really need this?
};
template <class T> Stack<T>::Stack( int capacity )
: _capacity { capacity }
, _stack { new T[_capacity] }
, _size {} //stack is empty
{
}
It's not necessary to have both _top and _size because one can be calculated from the other.
ChesterPlus wrote:
T dummy; // Something to return in case there was an error on the Top()
Enoiza wrote:
T dummy; // ??? Do your really need this?
This might have made sense if Top() returned a reference, but in that case you might want to store it as a static variable so that you only have to store one dummy object per element type instead of having each stack object contain its own.
Now Top() doesn't return a reference and you don't make use of the dummy object (calling Top() on an empty stack leads to undefined behaviour) so it doesn't look like your current code, the way it is written right now, needs a dummy object.
If you change Top() to return a reference and you want to allow calling it on an empty stack (which would be consistent with how Push and Pop works) then you might want to return a reference to the dummy object. Another perhaps more idiomatic alternative would be to throw an exception.