Problem with my first Stack-Class

Started by
12 comments, last by _goat 17 years, 8 months ago
Heh, learn a new C++ quirk every day, I guess [smile]

Wielder of the Sacred Wands
[Work - ArenaNet] [Epoch Language] [Scribblings]

Advertisement
Well, it took me a while, but I made my own little dynamic-array-class and the appropiate stack-class.
Here is what I got:
// hDynamicArray.h#ifndef hDynamicArray__H#define hDynamicArray__Htemplate<typename T>class DynamicArray {	unsigned int size;	unsigned int incrementSize;	unsigned int counter;	T* storage;		//	// Increases the size of the array	//	void increaseSize() {		unsigned int oldSize = size;		size = size + incrementSize;		T* storageTemp = new T[oldSize];				// Save old data		for(unsigned int i = 0; i <= oldSize; i++) {			storageTemp = storage;		}				delete []storage;		storage = new T[size];				// Copy old data to the new memory		for(unsigned int i = 0; i <= oldSize; i++) {			storage = storageTemp;		}				delete []storageTemp;	}public:	//	// The constructor	//	DynamicArray(unsigned int theSize, unsigned int theIncrementSize)	: size(theSize), incrementSize(theIncrementSize), counter(0), storage(NULL) {		storage = new T[theSize];	}		//	// Copy-constructor	//	DynamicArray(const T& n) {		size = n.size;		incrementSize = n.incrementSize;		counter = n.counter;				storage = n.storage;	}		//	// The destructor, which frees memory	//	virtual ~DynamicArray() {		delete []storage;		storage = NULL;	}		//	// Add an item	//	void add(const T& data) {		if(counter >= size) {			increaseSize();		}		storage[counter++] = data;	}		//	// Change an item at the given index	//	void changeItem(const T& data, int index) {		storage[index] = data;	}		//	// Return an item at the given index	//	T getItem(int index, bool decrementCounter = false) {		// Put an exception here, if I know		// more about it, but for now		// this has to be sufficient! ;)		if(index >= counter) {			index = 0;		}				if(decrementCounter == true) {			counter--;		}				return storage[index];	}		//	// Alias function for 'getItem()'	// Overload the []-operator	//	T operator[](int index) const {		return getItem(index);	}		//	// Overload the assignment-operator	//	T& operator=(const T& n) {		if(this != &n) {			size = n.size;			incrementSize = n.incrementSize;			counter = n.counter;						delete []storage;			storage = n.storage;		}				return *this;	}		//	// Return the counter	//	unsigned int getCounter() const {		return counter;	}		//	// Return the current size of the array	//	int getSize() const {		return size;	}};#endif hDynamicArray__H


// hSTACK.h#ifndef hSTACK__H#define hSTACK__H#include "hDynamicArray.h"#include <iostream>template <class T>class Stack {	DynamicArray<T>* container;public:	//	// The Constructor	//	Stack(unsigned int theSize, unsigned int incrementSize = 5) : container(NULL) {		container = new DynamicArray<T>(theSize, incrementSize);	};		//	// Copy-Constructor	//	Stack(const T& n) {		container = n.container;	}		//	// The destructor	// Release the occupied memory	//	virtual ~Stack() {		delete[] container;	}		//	// Overload the assignment-operator	//	T& operator=(const T& n) {		if(this != &n) {			delete container;			container = n.container;		}				return *this;	}		//	// Push something on the stack	//	void push(const T& data) {		container->add(data);	};	//	// Pop something from the stack	//	T pop() const {		if(container->getCounter() >= 0) {			return container->getItem((container->getCounter()) - 1, true);		} else {			return NULL;		}	};		//	// Peek the last object from the stack	//	T& peek() const {		return container->getItem((container->getCounter()) - 1);	};};#endif hSTACK__H


// main.cpp for testing purpose#include <iostream>#include <vector>#include "hStack.h"#include "hDynamicArray.h"using namespace std;int main() {	DynamicArray<int> Test(10, 5);		Test.add(5);	Test.add(10);	Test.add(15);		DynamicArray<int> Yea(2, 3);	Yea.add(22);	Yea.add(222);	Yea.add(222);	Yea.add(22);	Yea.add(222);	Yea.add(333);		Test = Yea;		Stack<int> myStack(3, 5);	myStack.push(77);	myStack.push(6);	myStack.push(7);	myStack.push(8);		Stack<int> blob = myStack;		cout << myStack.pop() << endl;	cout << myStack.pop() << endl;	cout << myStack.pop() << endl;	cout << myStack.pop() << endl;	cout << myStack.pop() << endl;	cout << myStack.pop() << endl;		// Required to keep the program from exiting	char x;	cin >> x;		return 1;}


Maybe someone could take a quick look at it and give me some hints on what to improve. To be more specific, I'm not really sure, if the "DynamicArray::increaseSize()"-method is very efficient because of the loop used for copying. There is a better way for this, right? Something like "memcpy()", I guess (I've never used the function or heard much about it, but see it often in context with dynamic arrays).

What the classes are definately missing is exception-handling, will add that, when I get in touch with the topic.

Is the OOP-structure of the classes right? I think, Stack does just the absolute nercassary things now, or to be more precise, it does just what it should AFAIK.

One little VERY weird problem I have is the Stack::pop()-method:
I have to use container->getItem() to return an item, I cannot use container[index]. It always gives me this error message:
"error C2440: 'return' : cannot convert from 'DynamicArray<T>' to 'int'"
What? It should return an integer when I run the example above. When I define a a DynamicArray-variable in main() and use "cout << testDArray[0];" it works like it's supposed to, but not inside the class? Someone enlighten me, please.

Well, at least my first copy-constructors and overloaded-operators work. ;)
Didn’t read over the entire thread, but incase it hasn’t been mentioned, you are reinventing the wheel. std::stack already exists and is what you should be using, and std::vector instead of your DynamicArray. Although if this is for purely educational purposes so that you can learn the language better than I'd say you’re off to a fine start.



Also I think
	T operator[](int index) const {		return getItem(index);	}


should return a reference to T instead. This will allow you to change its value using the [] operator. Currently this only allows you to retrieve values.

Quote:Original post by ApochPiQ
Heh, learn a new C++ quirk every day, I guess [smile]


I don't think it's so much a quirk as it is a way of forcing people to remember that you wouldn't be able to have a templated int. It has to be a class. Still, C++ for the quirks.
[ search: google ][ programming: msdn | boost | opengl ][ languages: nihongo ]

This topic is closed to new replies.

Advertisement