Operator Overloading

I was trying to follow(trace) various function invocations using the below program:

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
#include <iostream>
#include <cstring>

using namespace std;

class stringclass
{
	char * s;
	
	public:
	
	stringclass(): s(NULL) {cout<<"DC is invoked"<<endl; } //DC
	
	~stringclass() // Destructor
	{ 
		delete [] s;
		cout<<"Destructor is invoked"<<endl;
	}
	
	stringclass(char* str) // Parameter Constructor
	{
		s= new char[40];
		strcpy(s,str);
		cout<<"PC is invoked"<<endl;
		
	}
	
	stringclass(const stringclass& str)//Copy Constructor
	{
	  s= new char[40];
	  strcpy(s,str.s);
	  cout<<"CC is invoked"<<endl;
	}
	
	stringclass& operator=(const stringclass& str) //Overloaded Assign operator
	{
	  s= new char[40];
	  strcpy(s,str.s);
	  cout<<"Overloaded assign is invoked"<<endl;
	  return *this;
	}
	
	stringclass operator+(const stringclass& b) //overloaded + operator
	{
		stringclass c(*this);
		strcat(c.s,b.s);
		cout<<"Overloaded + is invoked"<<endl;
		return c;
	}
	
	friend ostream& operator<< (ostream &out, const stringclass & a); //overloaded << operator

};

ostream& operator<< (ostream &out, stringclass & a) //friend function
{
    cout << a.s;
    return out;
}

int main()
{
   stringclass str1("beau");
   stringclass str2("tiful");
   stringclass str3 = str1 + str2;
   cout<<str3<<endl;
   return 0;
}


The o/p is as below:

1
2
3
4
5
6
7
8
PC is invoked
PC is invoked
CC is invoked <= which value is being copied? the owner object?
Overloaded + is invoked 
beautiful 
Destructor is invoked
Destructor is invoked
Destructor is invoked


I feel a couple of things are missing before 'beautiful' is printed on the screen:

1) The value returned by str1+str2 should invoke a CC because str3 is being created
2) Creating a temporary object C should invoke a CC and destructor.

any idea why they are missing from the o/p?

I feel like your compiler is throwing some optimizations in there which are throwing off your output.

The CC comes from the addition operator because you're creating a new stringclass with (*this) as the parameter, where *this is str1.
Then naturally "Overloaded + is invoked" is output.

This is where I think your compiler simply shrunk str3 and (str1+str2) into one stringclass, and instead of constructing str3, it simply used the return value from the + operator.
Your code shall not be compiled because function operator << has no access to member s of your class stringclass. You declared as a friend function the function

friend ostream& operator<< (ostream &out, const stringclass & a);

that has const reference as the second parameter. But you defined other operator <<

ostream& operator<< (ostream &out, stringclass & a)

that uses non const reference as the second parameter.

Also your copy assignment operator contains a bug because it does not free memory used by s before assigning it new value.

As for your question the compiler uses optimization.
Last edited on
you should have least 2 member in the classstring, 's' to storing the string and 'len' for its lenght.
Then, in the assignment operator why you use 40 as the new size of the string? the rvalue of the operand can be greater then 40 char, then you just use the function strlen() of <cstring> or the 'len' member.
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
clas stringclass{
    // - - - - - 
    char *s;
    int len;  //for the lenght of the string
    // - - - - -
};

//without 'len' member
stringclass& operator=(const stringclass& str) //Overloaded Assign operator{
    if( &str == this) return *this;  //check if you are assign the same object
    int len=strlen(str.s);  //the length of the string
    if(s) delete [] s; //if the actual string is not null, delete old value
    s=new char[len + 1];
    strcpy(s,str.s);
    cout<<"Overloaded assign is invoked"<<endl;
    return *this;
}

//or with 'len' member in the class
stringclass& operator=(const stringclass& str) //Overloaded Assign operator{
    if( &str == this) return *this;  //check if you are assign the same object
    len=str.len;  //the length of the string
    if(s) delete [] s; //if the actual string is not null, delete old value
    s=new char[len + 1];
    strcpy(s,str.s);
    cout<<"Overloaded assign is invoked"<<endl;
    return *this;
}

Thanks guys. I get the optimization part.

@vlad: Yep..my bad ..pasted the old code with the const missing
with regards to the bug in CC. Isn't CC invoked when a new Object is created and you want to initialize it with an existing object. In that case the new object will point to what we make to to point at in the CC definition and won't have any prior assignment to it - that means no bug. Let me know if I got that wrong.

@Vins: Was trying to keep the code simple. Didn't bother much about the lenght thing. But thanks for pointing out the mistake I made in the assignment op code. Forgot to delete the resource there.
with regards to the bug in CC


The "copy assignment operator" is not the copy constructor.
oops..I read it as CC and thats why the confusion.
Topic archived. No new replies allowed.