Is this possible (= operator overloading question)

I'm overloading the = operator for a class that uses deep copying for its copy constructor. First let me post the relevant code:

class declaration (in stack.h)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
typedef unsigned long Item; //change to fit appropriate Item

class Stack
{
private:
	enum {MAX = 10};
	Item* pitems;
	int size; //number of elements in stack
	int top; //index for top stack item
public:
	Stack(int n = 10); //creates stack with n elements
	Stack(const Stack& st);
	~Stack();
	bool isempty() const;
	bool isfull() const;
	bool push(const Item& item); //add item to stack, returns false if stack is already full true otherwise
	bool pop(Item& item); //pop top into item, returns false if stack is already empty true otherwise
	Stack& operator=(const Stack& st);
};


copy constructor in stack.cpp
1
2
3
4
5
6
7
8
Stack::Stack(const Stack& st)
{
	pitems = new Item[st.size];
	for (int i = 0; i < size; ++i)
		pitems[i] = st.pitems[i];
	size = st.size;
	top = st.top;
}


= operator overload (in stack.cpp)
1
2
3
4
5
6
7
8
9
10
11
12
Stack& Stack::operator=(const Stack& st)
{
	if (this == &st)
		return *this;
	delete [] pitems; //causes problems
	pitems = new Item[st.size];
	for (int i = 0; i < size; ++i)
		pitems[i] = st.pitems[i];
	size = st.size;
	top = st.top;
	return *this;
}


Now everything is fine if I do something like this:
1
2
3
Stack obj_1;
Stack obj_2(5);
obj_2 = obj_1;


I get an error from applying delete [] to the uninitialized pitems of the obj_2 Stack if I do something like this:
1
2
Stack obj_1;
Stack obj_2 = obj_1; //uses = operator to initialize 


Is there a way to check if obj_2 has been initialized so I can determine whether or not to apply delete [] to pitems? Or some way to force the class user to initialize an object before using the overloaded = operator? Or a better solution I haven't thought of/don't know of?
delete and delete[] do nothing on null pointers.

So it is safe to delete[] pitems; if pitems is 0, aka NULL, aka nullptr.

Anyway, this all is moot, because:

1
2
3
4
5
6
7
Stack obj_1;
Stack obj_2 = obj_1; //uses = operator to initialize nope!

// the assignment above is not the operator= because it appears in a declaration

// basically the above is a shorthand for
Stack obj_2(obj_1);


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>

class Whine
{
public:

    Whine()
    {
        std::clog << "Default constructor for " << this << '\n';
    }

    Whine(const Whine &)
    {
        std::clog << "Copy constructor for " << this << '\n';
    }

    Whine & operator = (const Whine &)
    {
        std::clog << "Copy assignment operator for " << this << '\n';
        return *this;
    }

    ~Whine()
    {
        std::clog << "Destructor for " << this << '\n';
    }
};

int main()
{
    Whine a;
    Whine b = a;
}

Default constructor for 0x28ff0f
Copy constructor for 0x28ff0e
Destructor for 0x28ff0e
Destructor for 0x28ff0f


I get an error from applying delete [] to the uninitialized pitems of the obj_2 Stack if I do something like this:

In the end, are you sure this is what causes your problem?
In the end, are you sure this is what causes your problem?
Nope, because what was causing the problem was the uninitialized size variable in the copy constructor. So much wasted time, thanks for the answer it really helped.
Topic archived. No new replies allowed.