Overloading operators = problems

// example on constructors and destructors
#include <iostream>
using namespace std;

class CRectangle {
int *width, *height;
public:
CRectangle (int,int);
~CRectangle ();
int area () {return (*width * *height);}
void operator =(CRectangle orig);
};

CRectangle::CRectangle (int a, int b) {
width = new int;
height = new int;
*width = a;
*height = b;
}

void CRectangle::operator =(CRectangle orig)
{
*width = *orig.width;
*height = *orig.height;
}
CRectangle::~CRectangle () {
delete width;
delete height;
}

int main () {
CRectangle rect (3,4), rectb (5,6);
cout << "rect area: " << rect.area() << endl;
cout << "rectb area: " << rectb.area() << endl;
CRectangle rect1 = rect;
CRectangle rect2 (1,2);
rect2 = rect;
return 0;
}

/////////////////////////////////////////////////////////////////////////

Question1:
what difference between
1)CRectangle rect1 = rect;
and
2)CRectangle rect2 (1,2);
rect2 = rect;
why 1) still uses standard =, whereas 2) uses overloading = ?

Question2:
After calling overloading = function, destructor is called and delete the rect object. how to fix this problem?

Thank you very much for your helps

1
2
3
4
5
// This invokes the copy constructor:
CRectangle rect1 = rect;

// This invokes the assignment operator:
rect1 = rect;



Your problem is that you don't provide a copy constructor. As a general rule, if you need to write
an assignment operator, you also need to write a copy constructor (and vice versa).

But why on Earth are you dynamically allocating width and height in the first place???

EDIT: A better declaration of the assignment operator is:

1
2
3
4
CRectangle& operator=( CRectangle rhs ) {
   // ... do the work
   return *this;
}

Last edited on
But why on Earth are you dynamically allocating width and height in the first place???

@jsmith
Give him a break! :P He may just happen to want to test the need for an overloaded assignment operator.

Your problem is that you don't provide a copy constructor. As a general rule, if you need to write
an assignment operator, you also need to write a copy constructor (and vice versa).

@dqcyd
jsmith is absolutely right! Check this out:

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
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
// example on constructors and destructors
#include <iostream>
using namespace std;

class CRectangle {
    int *width, *height;
    public:
    CRectangle (int,int);
    CRectangle (const CRectangle & rect); //<- this is the copy constructor you need
    ~CRectangle ();
    int area () {return (*width * *height);}
    CRectangle & operator =(const CRectangle & orig);
    
    static int rect_count;
};

int CRectangle::rect_count=0;

CRectangle::CRectangle (int a, int b) {
    cout << "inside int constructor of rect " << ++rect_count;
    cout << " (a=" << a << ",b=" << b << ")\n" << flush;
    width = new int;
    height = new int;
    *width = a;
    *height = b;
}

CRectangle::CRectangle (const CRectangle & rect)
{
      cout << "inside copy constructor of rect " << ++rect_count;
      cout << " (width=" << *rect.width;
      cout << ",height=" << *rect.height << ")\n" << flush;
      width = new int;
      height = new int;
      *width=*rect.width;
      *height=*rect.height;                
}

CRectangle & CRectangle::operator =(const CRectangle & orig)
{
     cout << "inside operator= of rect " << rect_count << endl;
    *width = *orig.width;
    *height = *orig.height;
    return *this;
}

CRectangle::~CRectangle () {
    cout << "inside destructor of rect "<< rect_count--<< endl;
    delete width;
    delete height;
}

class AfterMain 
{
      public:
      ~AfterMain()
      {
           cout << "hit enter to quit...\n";
           cin.get();
      }
};

AfterMain after_main; //like after shave :D

int main () {
    cout << "==================================================\n";
    cout << "let's see what happens inside main...\n";
    cout << "==================================================\n" << endl;
    CRectangle rect (3,4), rectb (5,6);
    cout << "rect area: " << rect.area() << endl;
    cout << "rectb area: " << rectb.area() << endl;
    
    CRectangle rect1 = rect; //<- this statement calls the copy constructor
                             //and NOT the (overloaded) assignment operator
    CRectangle rect2 (1,2);
    rect2 = rect; //<- this statement calls the (overloaded) assignment operator
    
    cout << "\n==================================================\n";
    cout << "and now let's see what happens when main returns...\n";
    cout << "==================================================\n" << endl;
    return 0;
}
Last edited on
m4ster roshi and jsmith, Thank you very much for your helps.

I definitely read about copy constructor before, but I think I just understand it now. (may be not fully)

"jsmith: But why on Earth are you dynamically allocating width and height in the first place???"

Yes, I just use this code to test overloaded assignment operator. Next time I will make code more clean and give prominence to the problem.

Thanks again
Topic archived. No new replies allowed.