Try this code:
#include <iostream>
#include <vector>
class MyClass
{
public:
MyClass(void)
{
std::cout << "constructor(void)" << std::endl;
};
MyClass(const MyClass& rhs)
{
std::cout << "constructor(copy)" << std::endl;
};
MyClass& operator=(const MyClass& rhs)
{
// check for self-assignment. saying a = a should have
// no effect.
if (this != &rhs)
{
std::cout << "operator=" << std::endl;
}
// note the return type. now return a reference to self
// to allow chaining: a = b = c = d;
// This is the standard way of implementing
// operator=, but wasn't related to your question too much.
// Just good to clarify on.
return *this;
};
~MyClass(void)
{
std::cout << "destructor" << std::endl;
};
};
int main(void)
{
std::cout << "1" << std::endl;
std::vector<MyClass> theArray;
std::cout << "2" << std::endl;
MyClass foo;
std::cout << "3" << std::endl;
theArray.push_back(foo);
std::cout << "4" << std::endl;
}
And you will get:
- 1
- 2
- constructor(void)
- 3
- constructor(copy)
- 4
- destructor
- destructor
Copy-construct versus operator=
The reason it is using the copy-constructor instead of operator= is because the object does not exist until the push_back.
That is, it's like saying this:
MyClass a;
MyClass b(a); // push_back
Rather than:
MyClass a;
MyClass b;
b = a; // push_back
The reason the first is used then is because whe you push_back, the object is created right at that call site inside the vector.
It would be silly for the vector to always call both the constructor(void), then operator=, rather than constructing directly from the original with one constructor(copy).
To further this point, something like:
MyClass a;
MyClass b = a;
With automatically be treated like this by the compiler:
MyClass a;
MyClass b(a);
So the standard itself (I don't know the exact quote, I know Neil Butterworth's does) says that this conversion should occur, because it's more correct.
Destructors
The reason there are two destructor's is that the vector has its destructor called, upon which is destructs all of it's contents. in this case, this is one instance of the class, and that accounts for one output of "destructor". Had you pushed n MyClass's on the vector, you'd have n calls to the destructor, one for each.
The second comes from destructing b.