Liam Laverty Liam Laverty - 27 days ago 12
C++ Question

C++ Creating a copy constructor for stack class

I have defined a stack class containing methods for pushing and popping values onto the stack.

In the tester file (shown below), after running it, an occur occurs & the program crashes. I know this is due to the function f, which creates an error as two pointers are pointing to the same location in memory. If i comment out the line f(s) when the function is called, the pop & push functions work correctly and the output is correct.

To fix this error, I have been asked to ; Create a copy constructor for this class to fix the above problem.

I'm not really familiar with this, so any help would be appreciated in how to do this. Thanks

Main Test file

#include "Stack.h"
#include <iostream>
#include <string>
using namespace std;

void f(Stack &a) {
Stack b = a;
}


int main() {

Stack s(2); //declare a stack object s which can store 2 ints
s.push(4); //add int 4 into stack s

//s = [4]
s.push(13); //add int 13 into stack s
//s = [4,13]

f(s); //calls the function f which takes in parameter Stack a , and sets Stack b = to it.
//error here - as 2 pointers point to the same location in memory !
cout << s.pop() << endl; //print out top element(most recently pushed) element.
//so should output 13
return 0;
}


Header File Code

#ifndef STACK_H
#define STACK_H

class Stack {
public:
//constructor
Stack(int size);

//destructor
~Stack();

//public members (data & functions)
void push(int i);
int pop();

private:
//private members (data & functions)
int stck_size;
int* stck;
int top;
};

#endif


Stack.cpp Code

#include "Stack.h"
#include <iostream>
#include <string>
using namespace std;

Stack::Stack(int size){
stck_size = size;
stck = new int[stck_size];
top = 0;
}
Stack::~Stack() {
delete[] stck;
}
void Stack::push(int i) {
if (top == stck_size) {
cout << "Stack overflow." << endl;
return;
}
stck[top++] = i;
}

int Stack::pop() {
if (top == 0) {
cout << "Stack underflow." << endl;
return 0;
}
top--; //decrement top so it points to the last element istead of the empty space at the top.
return stck[top];
}

Answer

Copy constructor here is pretty quick-and dirty:

Stack::Stack(const Stack & src): 
    stck_size(src.stack_size),
    stck(new int[stck_size]),
    top(src.top) //Member Initializer List
{
    // copy source's stack into this one. Could also use std::copy.
    // avoid stuff like memcpy. It works here, but not with anything more 
    // complicated. memcpy is a habit it's just best not to get into
    for (int index = 0; index < top; index++)
    {
        stck[index] = src.stck[index];
    }
}

Now that you have a copy constructor, you're still likely screwed because the Rule of Three has not been satisfied. You need operator=. And this is easy because the copy construct and the copy and swap idiom makes it easy.

Basic form:

TYPE& TYPE::operator=(TYPE rhs) //the object to be copied is passed by value
                                // the copy constructor makes the copy for us.
{
  swap(rhs); // need to implement a swap method. You probably need one 
             //for sorting anyway, so no loss.
  return *this; // return reference to new object
}