In the following code, I do not understand why isn't the copy constructor called for "ob3" in main and why isn't the destructor called for "temp" in overloaded operator function:
output is:
In the constructor with arguments 10 20
In the constructor with arguments 5 30
10 20
5 30
In copy constructor
In operator before temp
In the constructor with arguments 0 0
In operator after temp
In Destructor 5 30
15 50
In Destructor 15 50
In Destructor 5 30
In Destructor 10 20
~~~~~~~~~~~~~~~
Code is :
~~~~~~~~~~~~
#include <iostream>
using namespace std;
class loc {
int longitude, latitude;
public:
loc(int lg, int lt) {
longitude = lg;
latitude = lt;
cout << "In the constructor with arguments " << longitude <<" " << latitude << endl;
}
But you see ob3 did not exist before that statement was written. SO it is initialization for ob3 and so shouldn't copy constructor be called , because it is always called for initialization...isn't it.
Another thing , if I replace the statement
loc ob3 = (ob1 + ob2);
by
loc ob3 = ob1;
then copy constructor is called !
Whats the difference ? In both cases we are initializing a newly constructed object ob3 !
Then why the difference in behavior ?
Ankur
In C++, there is a thing called (if I remember the term correctly) Conversion by constructor where a statement like loc ob3 = ob1; is treated the same as loc obj3(obj1). (Note this applies only to constructors taking 1 parameter)
So if you have a class like this
1 2 3 4
class myX
{
myX (int a) {} //constructor taking 1 parameter
};
you can say MyX x1 = 3 and the compiler will implicitly use the myX (int a) constructor.
This implicit conversion can be confusing sometimes because it looks like you are assigning n
integer to a class. If you don't want this implicit conversion to take place, then you can use
the explicit keyword on the constructor.
1 2 3 4
class myX
{
explicit myX (int a) {} //constructor taking 1 parameter
};
So now MyX x1 = 3 will give an error.
I'm trying to find a link to some documents that have a better explaination
But in my case I still don't understand why copy constructor is not called for
loc ob3 = (ob1 + ob2);
You see ob1+ob2 is returning an object and ob3 is being initialized with that object. This is not different than using just one object for initialization as loc ob3 = ob1;
And copy constructor is always called when a non existing object is initialized using another object. But my case differs some how and I don't understand how ?
In the output I have posted in the very first post, copy constructor is called only once and that is when op2 in the operator function is getting initialized.
This is all "to my knowledge" and I might not be 100% right on this... but this is the way I understand it:
But in my case I still don't understand why copy constructor is not called for
loc ob3 = (ob1 + ob2);
You're not explicitly calling the copy ctor there. Therefore the compiler is free to make optimizations where it deems appropriate (this is a good thing!)
Here, instead of a temporary object being created, copied, then destroyed, it just treats 'ob3' as the temporary object so a copy isn't needed, and thus it doesn't need to be destroyed. This removes a lot of unnecessary code, and the end result is the same.
If you want to bypass the optimization and force the copy ctor, I believe you can do it explicitly with this:
1 2
// just tried it -- this doesn't work
loc ob3 = loc( ob1 + ob2 ); // explicitly using the copy ctor here, so it must be called
EDIT: I just tried by idea of explicitly calling the copy ctor and it doesn't work. *shrug*
Don't know how to bypass the optimization then. But then again I don't see why you'd ever want to.
In that case, it is probably a compiler thing.
I tried it with both mingw and MSVC and get two slightly different outputs.
MINGW (using GCC)In the constructor with arguments 10 20
In the constructor with arguments 5 30
10 20
5 30
In copy constructor
In operator before temp
In the constructor with arguments 0 0
In operator after temp
In Destructor 5 30
15 50
In Destructor 15 50
In Destructor 5 30
In Destructor 10 20
MSVCIn the constructor with arguments 10 20
In the constructor with arguments 5 30
10 20
5 30
In copy constructor
In operator before temp
In the constructor with arguments 0 0
In operator after temp
In copy constructor
In Destructor 15 50
In Destructor 5 30
15 50
guestgulkan, is that the complete output from MSVC ?
I think three objects must be destroyed at the end.
Disch, I tried calling the copy constructor explicitly using
loc ob3 = loc(ob1 + ob2);
but it still did not call it.
I am on g++
gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-47)
It could be a compiler thing.
Now that we are on it, consider this:
If I comment out the
return temp;
in operator function, then ob3 still gets some garbage values.
But, why should that happen ? You see ob3 was never constructed in the first place, two reasons: There is no , no argument constructor for the class. Second , there was no return value. So if ob3 never got a chance to be constructed , there is no memory allocated to that object. Then why print garbage values ? I feel this should be a compile time error. In java it would be a compile time error.
The full msvc output looks like this: In the constructor with arguments 10 20
In the constructor with arguments 5 30
10 20
5 30
In copy constructor
In operator before temp
In the constructor with arguments 0 0
In operator after temp
In copy constructor
In Destructor 15 50
In Destructor 5 30
15 50
In Destructor 15 50
In Destructor 5 30
In Destructor 10 20