Reputation: 35522
So I use a dynamic stack and I want to write a copy constructor, which has to copy the stack's data from another instance of the same class. I'm trying to write the function, but it seems pretty hard. Could somebody give me a hand?
template<typename T=int>
class LStack
{
public:
template<typename U=int>
struct elem
{
U con;
elem<U>* link;
}
private:
elem<T>* el;
void Copystack(Lstack const& stack) // HERE
{
elem<T>* last = el;
el->con = stack->con;
while(stack->link != null)
{
var temp = new elem<T>;
temp->con = stack->con;
temp->link = stack->link;
stack = stack->link;
}
}
};
Upvotes: 4
Views: 31328
Reputation: 104514
First, if you are going to support copying a collection class, you need to be able to property release the memory owned by the stack object your are copying into, else you have a memory leak. The kind of thing your destructor would do anyway. So let's have a clean
method:
void clean() {
while (el) {
auto ptr = el;
el = el->link;
delete ptr;
}
el = nullptr;
}
Then cloning a stack is cloning your linked list. It doesn't matter that your linked list represents a stack or a queue when we clone it. We're just preserving order.
void clone(elem<T>* ptr) {
clean(); // erase the current stack
elem<T>* head = nullptr;
elem<T>* last = nullptr;
while (ptr) {
// clone the item
elem<T>* item = new elem<T>();
item->con = ptr->con;
item->link = nullptr;
// appead the item at the end of our new linked list
if (head == nullptr) {
head = item;
} else {
last->link = item;
}
last = item;
ptr = ptr->link;
}
el = head;
}
Then enables you to have a copy method:
LStack& operator=(const LStack& other) {
clone(other.el);
return *this;
}
And a copy constructor, which sets the head of the linked list to null before cloning the other one.
LStack(const LStack& other) : el(nullptr) {
clone(other.el);
}
And your CopyStack function, if you still want it, does the same thing.
CopyStack(const LStack& other) {
clone(other.el);
}
And let's not forget your destructor can invoke the clean method:
~LStack() {
clean();
}
Upvotes: 0
Reputation: 25
/*Create two stack objects of the same data type.
Push elements into the original stack.
Copy the original stack into the new stack using the assignment operator.
Traverse the copied stack using a loop.
For each element in the copied stack, perform the following operations:
Retrieve the top element of the copied stack using the top() function.
Store the top element of the copied stack in a variable.
Pop the top element of the copied stack using the pop() function.
Push the stored element into the new stack using the push() function.
Print the elements of the new stack*/
#include <iostream>
#include <stack>
int main() {
std::stack<int> originalStack;
std::stack<int> copiedStack;
std::stack<int> newStack;
// Push elements into the original stack
originalStack.push(10);
originalStack.push(20);
originalStack.push(30);
// Copy the original stack into the copied stack
copiedStack = originalStack;
// Traverse the copied stack and push its elements into the new stack
while (!copiedStack.empty()) {
int element = copiedStack.top();
copiedStack.pop();
newStack.push(element);
}
// Print the elements of the new stack
while (!newStack.empty()) {
std::cout << newStack.top() << " ";
newStack.pop();
}
return 0;
}
Upvotes: 0
Reputation: 70526
The STL container adaptor std::stack
has an assignment operator=
that allows you to do exactly that
#include <stack>
int main()
{
std::stack<int> s1;
std::stack<int> s2;
s1 = s2;
}
If you need to do it manually, you can use @FredOverflow's recursive solution, or you could do it with two loops and a temporary Stack, which the recurisve version keeps on the stack frame (pun intended).
void copy_reverse(Stack& source, Stack& dest)
{
while(!source.empty())
dest.push(Element(source.top()));
source.pop();
}
}
Stack src, tmp, dst;
copy_reverse(src, tmp);
copy_reverse(tmp, dst);
Upvotes: 8