Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • "this" is not same at whole class?
  • at first part of output are "set 1." same and at second part of output are "set 1." different?
  • "set 1." different from ctor? (if it is due to making new object or something like that why it is made?)
  • "a" equals "set 1." and "ctor" / "dtor" (at the end) equals "set 2." ?
  • "set 1." calling dtor?
like image 686
uzivanky Avatar asked Feb 21 '26 00:02

uzivanky


1 Answers

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!

like image 124
Klaus Avatar answered Feb 24 '26 06:02

Klaus



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!