Sorry, I can't explain it either. I thought I would be able to. I presumed another of the default functions the compiler supplies, namely the default copy constructor, was invisibly executing behind the scenes instead of the operator= function, but when I explicitly defined a copy constructor for the Apple class, it wasn't called either. I put display messages in the default constructor and the int constructor as well, and none of them displayed a message. So, it appears newApple is being created without a call to a constructor, which is impossible. One of the pros will have to weigh in on that, but I doubt any of them will wade through all these posts and end up here.
Below is the code with all the possible constructors defined: the default constructor, an int constructor, and the copy constructor. A copy constructor is called when you construct an object with another object:
Apple newApple(myApple);
A copy constructor is also called when you initialize an object, i.e. you create an object and assign it another object in the same statement:
Apple newApple = myApple;
And, a copy constructor is called when you "pass by value"--the copy constructor is what's used to make a copy of the object for the function.
If you remember from the discussion earlier, the operator+ created a new object inside the function, which was the sum of the two objects, and the function returned the new object "passing by value". Therefore, it was my expectation that when the following statement executed in main():
Apple newApple = myApple + yourApple;
instead of the operator= being called, the copy constructor would be called twice: once when the operator+ returned an object "passing by value",
Apple newApple = (myApple + yourApple)
and once for the initialization that occurs in that statement,
Apple newApple = (an Apple object returned by operator+);
However, the code below shows in green what the actual output from the constructors is:
Code:
#include <iostream>
using namespace std;
class Apple
{
public:
int num;
Apple()
{
cout<<"default constructor called"<<endl;
}
Apple(int n)
{
cout<<"int constructor called"<<endl;
num = n;
}
Apple(const Apple& anApple)
{
cout<<"copy constructor called"<<endl;
num = anApple.num;
}
Apple operator+(const Apple& rhs) const
{
cout<<"operator+ called"<<endl;
return Apple(num + rhs.num);
}
Apple& operator=(const Apple& rhs)
{
if(this == &rhs) //checks to see if lhs and rhs are the same objects
{
cout<<"they're equal, exiting function directly"<<endl;
return *this; //if lhs==rhs, then executing the code below is unnecessary
}
cout<<"assignment operator called"<<endl;
num = rhs.num;
return *this;
}
};
int main()
{
Apple myApple; //default constructor called
myApple.num = 10;
Apple yourApple; //default constructor called
yourApple.num = 30;
Apple newApple = myApple + yourApple; //operator+ called
//int constructor called
cout<<endl<<newApple.num<<endl; //40
return 0;
}
The copy constructor is not called at all. One of the cboard pros, Stoned_Coder, explained that puzzling output: the compiler takes over and does some optimization. According to the C++ standard, the compiler doesn't have to create a copy when operator+ returns the new object if the return statement is written like this:
return Apple(num + rhs.num);
so my compiler didn't. In addition, my compiler didn't call the copy constructor to copy the object on the rhs of the equal sign into the object being created on the lhs. Instead, the object went straight into the memory being created for newApple, and the int constructor was called to initialize its members.