Reputation: 128
I played around with class and came across this curiosity
#include <iostream>
#include <Windows.h>
class pint {
public:
pint() { std::cout << "ctor >> " << this << std::endl; };
~pint() { std::cout << "dtor >> " << this << std::endl; };
pint(int x) { std::cout << "set 1. >> " << this << std::endl; };
pint& operator = (const pint& a) { std::cout << "set 2. >> " << this << " | a >> " << &a << std::endl; return *this; };
};
int main()
{
pint * x1 = new pint;
*x1 = 8;
*x1 = 9;
std::cout << "---------------------" << std::endl;
pint * x2 = new pint;
*x2 = 8;
*x2 = 9;
std::cout << "---------------------" << std::endl;
delete x1;
delete x2;
while (!GetAsyncKeyState(VK_RETURN))
Sleep(1);
return 0;
}
OUTPUT:
ctor >> 008731E8
set 1. >> 005BF9A7
set 2. >> 008731E8 | a >> 005BF9A7
dtor >> 005BF9A7
set 1. >> 005BF9A7
set 2. >> 008731E8 | a >> 005BF9A7
dtor >> 005BF9A7
---------------------
ctor >> 00873288
set 1. >> 005BF9A7
set 2. >> 00873288 | a >> 005BF9A7
dtor >> 005BF9A7
set 1. >> 005BF9A6
set 2. >> 00873288 | a >> 005BF9A6
dtor >> 005BF9A6
---------------------
dtor >> 008731E8
dtor >> 00873288
why:
Upvotes: 3
Views: 116
Reputation: 25603
The interesting thing here is, that you have not only one object! You generate some temporary ones.
*x1 = 8;
The class pin did not have a operator=(int)
, but it can generate a pint object via int. So the constructor pint(int)
is called. That new object with new address can now be given to operator(const pint&)
That is the reason you see your "set1" text. The "8" will first create a temporary pint object, which has a new address.
The "magic" goes away if you add:
pint& operator = (const int a) { std::cout << "set 3. >> " << this << " | a >> " << &a << std::endl; return *this; };
Another way to see that your compiler generates an intermediate temporary with a constructor which is able to do a "unwanted cast", you can make the conversion constructor explicit
.
use:
explicit pint(int x){...}
Now your compiler gives you an error about that!
Upvotes: 5