vector.push_back работает с добавлением указателя на объект, но не с добавлением объекта
Я пытаюсь реализовать стек, используя набор вложенных стеков фиксированной длины. Для подстека я использую простой массив фиксированной длины, инициализированный в конструкторе. Для стека я использую вектор вложенных стеков.
Приведенный ниже метод push пытается выделить память для нового подстека и передать его в вектор. Но всякий раз, когда происходит новый запрос (скажем, на вектор setofstacks[1], предыдущий setofstacks[0] получает значения мусора при вызове деструктора subtack. Не уверен, почему это происходит.
vector<substack<T>> setofstacks;
substack<T> *s = new substack<T>(size);
setofstacks.push_back(*s);
setofstacks[currStackIndex].push(elem);
С другой стороны, если я преобразую объект в указатель объекта подстека и сохраню его в векторе, это прекрасно работает.
vector<substack<T>*> setofstacks;
setofstacks.push_back(new substack<T>(size));
setofstacks[currStackIndex]->push(elem);
Не работает полный код
/* Program: Implement a stack of substacks of fixed size
*
* Date: 12/28/2015
*/
#include <iostream>
#include <vector>
using namespace std;
template <class T>
class substack
{
private:
T *arr;
int nextAvailable;
int size;
public:
substack(int capacity);
~substack();
void push(T elem);
T pop();
T peek();
bool isfull();
bool isempty();
};
// Constructor initializing size of substack
template <class T>
substack<T>::substack(int capacity)
{
nextAvailable = 0;
size = capacity;
arr = new T[capacity];
}
// Destructor freeing memory allocated by the stack implemented using array
template <class T>
substack<T>::~substack()
{
delete[] arr;
arr = NULL;
}
// Pushing an element on top of a substack of fixed size
template <class T>
void substack<T>::push(T elem)
{
if (nextAvailable < size)
{
arr[nextAvailable] = elem;
nextAvailable++;
}
else
{
cout << "Substack is full" << endl;
return;
}
}
// Popping the top element from a stack of fixed size
template <class T>
T substack<T>::pop()
{
nextAvailable--;
if (nextAvailable >= 0)
{
T del = arr[nextAvailable];
arr[nextAvailable] = NULL;
return del;
}
else
{
cout << "Stack is empty" << endl;
return NULL;
}
}
// Peeking the top element from a stack of fixed size
template <class T>
T substack<T>::peek()
{
if (nextAvailable > 0)
{
return arr[nextAvailable - 1];
}
else
{
cout << "Stack is empty" << endl;
return NULL;
}
}
// Checking if a substack is full or not
template <class T>
bool substack<T>::isfull()
{
return (nextAvailable == size);
}
// Checking if a substack is empty or not
template <class T>
bool substack<T>::isempty()
{
return (nextAvailable == 0);
}
template <class T>
class SetOfStacks
{
private:
//vector<substack<T>*> setofstacks;
vector<substack<T>> setofstacks;
int currStackIndex;
int size;
public:
SetOfStacks(int capacity);
~SetOfStacks();
void push(T elem);
T pop();
T peek();
};
// Constructor initializing a set of stacks
template <class T>
SetOfStacks<T>::SetOfStacks(int maxStackCapacity)
{
currStackIndex = 0;
size = maxStackCapacity;
substack<T> *s = new substack<T>(maxStackCapacity);
setofstacks.push_back(*s);
//setofstacks.push_back(new substack<T>(maxStackCapacity));
}
// Destructor clearing set of stacks vector
template <class T>
SetOfStacks<T>::~SetOfStacks()
{
setofstacks.clear();
}
// Pushing an element on top of a stack implemented by a set of fixed length substacks
template <class T>
void SetOfStacks<T>::push(T elem)
{
if (!setofstacks[currStackIndex].isfull())
{
setofstacks[currStackIndex].push(elem);
}
else
{
currStackIndex++;
substack<T> *s = new substack<T>(size);
setofstacks.push_back(*s);
//setofstacks.push_back(new substack<T>(size));
setofstacks[currStackIndex].push(elem);
}
}
// Popping an element from top of a stack implemented by a set of fixed length substacks
template <class T>
T SetOfStacks<T>::pop()
{
if (!setofstacks[currStackIndex].isempty())
{
return setofstacks[currStackIndex].pop();
}
else
{
setofstacks.pop_back();
currStackIndex--;
if (currStackIndex >= 0)
{
return setofstacks[currStackIndex].pop();
}
else
{
cout << "Stack is empty" << endl;
return NULL;
}
}
}
// Peeking an element from top of a stack implemented by a set of fixed length substacks
template <class T>
T SetOfStacks<T>::peek()
{
return setofstacks[currStackIndex].peek();
}
int main()
{
SetOfStacks<int> *s = new SetOfStacks<int>(5);
s->push(1);
s->push(2);
s->push(3);
s->push(4);
s->push(5);
s->push(6);
s->push(7);
s->push(8);
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
s->push(1);
s->push(2);
s->push(3);
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
//cout << s->pop() << endl;
system("pause");
}
Выход
8
7
6
-572662307
-572662307
-572662307
-572662307
-572662307
3
2
1
Press any key to continue . . .
Рабочий код
/* Program: Implement a stack of substacks of fixed size
*
* Date: 12/28/2015
*/
#include <iostream>
#include <vector>
using namespace std;
template <class T>
class substack
{
private:
T *arr;
int nextAvailable;
int size;
public:
substack(int capacity);
~substack();
void push(T elem);
T pop();
T peek();
bool isfull();
bool isempty();
};
// Constructor initializing size of substack
template <class T>
substack<T>::substack(int capacity)
{
nextAvailable = 0;
size = capacity;
arr = new T[capacity];
}
// Destructor freeing memory allocated by the stack implemented using array
template <class T>
substack<T>::~substack()
{
delete[] arr;
arr = NULL;
}
// Pushing an element on top of a substack of fixed size
template <class T>
void substack<T>::push(T elem)
{
if (nextAvailable < size)
{
arr[nextAvailable] = elem;
nextAvailable++;
}
else
{
cout << "Substack is full" << endl;
return;
}
}
// Popping the top element from a stack of fixed size
template <class T>
T substack<T>::pop()
{
nextAvailable--;
if (nextAvailable >= 0)
{
T del = arr[nextAvailable];
arr[nextAvailable] = NULL;
return del;
}
else
{
cout << "Stack is empty" << endl;
return NULL;
}
}
// Peeking the top element from a stack of fixed size
template <class T>
T substack<T>::peek()
{
if (nextAvailable > 0)
{
return arr[nextAvailable - 1];
}
else
{
cout << "Stack is empty" << endl;
return NULL;
}
}
// Checking if a substack is full or not
template <class T>
bool substack<T>::isfull()
{
return (nextAvailable == size);
}
// Checking if a substack is empty or not
template <class T>
bool substack<T>::isempty()
{
return (nextAvailable == 0);
}
template <class T>
class SetOfStacks
{
private:
vector<substack<T>*> setofstacks;
int currStackIndex;
int size;
public:
SetOfStacks(int capacity);
~SetOfStacks();
void push(T elem);
T pop();
T peek();
};
// Constructor initializing a set of stacks
template <class T>
SetOfStacks<T>::SetOfStacks(int maxStackCapacity)
{
currStackIndex = 0;
size = maxStackCapacity;
//substack<T> *s = new substack<T>(maxStackCapacity);
setofstacks.push_back(new substack<T>(maxStackCapacity));
}
// Destructor clearing set of stacks vector
template <class T>
SetOfStacks<T>::~SetOfStacks()
{
setofstacks.clear();
}
// Pushing an element on top of a stack implemented by a set of fixed length substacks
template <class T>
void SetOfStacks<T>::push(T elem)
{
if (!setofstacks[currStackIndex]->isfull())
{
setofstacks[currStackIndex]->push(elem);
}
else
{
currStackIndex++;
//substack<T> *s = new substack<T>(size);
setofstacks.push_back(new substack<T>(size));
setofstacks[currStackIndex]->push(elem);
}
}
// Popping an element from top of a stack implemented by a set of fixed length substacks
template <class T>
T SetOfStacks<T>::pop()
{
if (!setofstacks[currStackIndex]->isempty())
{
return setofstacks[currStackIndex]->pop();
}
else
{
setofstacks.pop_back();
currStackIndex--;
if (currStackIndex >= 0)
{
return setofstacks[currStackIndex]->pop();
}
else
{
cout << "Stack is empty" << endl;
return NULL;
}
}
}
// Peeking an element from top of a stack implemented by a set of fixed length substacks
template <class T>
T SetOfStacks<T>::peek()
{
return setofstacks[currStackIndex].peek();
}
int main()
{
SetOfStacks<int> *s = new SetOfStacks<int>(5);
s->push(1);
s->push(2);
s->push(3);
s->push(4);
s->push(5);
s->push(6);
s->push(7);
s->push(8);
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
s->push(1);
s->push(2);
s->push(3);
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
cout << s->pop() << endl;
system("pause");
}
Выход
8
7
6
5
4
3
2
1
3
2
1
Stack is empty
0
Press any key to continue . . .
Пожалуйста, дайте мне знать, что мне не хватает в использовании push_back при добавлении фактического объекта substack, чтобы он не испортил предыдущий индексный стэк в векторе.
Не уверен, как это обмануть правило трех. Мне не хватает одного из трех копий конструктора, оператора присваивания? Пожалуйста, помогите мне понять.