uzivanky
uzivanky

Reputation: 128

different "this" at class

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

Answers (1)

Klaus
Klaus

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

Related Questions