代码之家  ›  专栏  ›  技术社区  ›  uzivanky

课堂上不同的“this”

  •  3
  • uzivanky  · 技术社区  · 6 年前

    我在课堂上玩耍,偶然发现了这种好奇心

    #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;
    }
    

    输出:

    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
    

    原因:

    • “这个”在全班都不一样吗?
    • 输出的第一部分是“设置1”输出的第二部分和第二部分是“设置1”不同的
    • “设置1。”与ctor不同?(如果是因为制作新对象或类似的东西,为什么要制作?)
    • “a”等于“集合1”“ctor”/“dtor”(在末尾)等于“set 2”?
    • “设置1。”呼叫dtor?
    1 回复  |  直到 6 年前
        1
  •  5
  •   Klaus    6 年前

    有趣的是,你不仅仅有一个物体!您生成了一些临时的。

    *x1 = 8;
    

    类pin没有 operator=(int) ,但它可以通过int生成一个pint对象 pint(int) 被调用。现在可以将具有新地址的新对象提供给 operator(const pint&)

    这就是您看到“set1”文本的原因。“8”将首先创建一个临时pint对象,该对象有一个新地址。

    如果您添加以下内容,“魔力”就会消失:

    pint& operator = (const int a) { std::cout << "set 3. >> " << this << " | a >> " << &a << std::endl; return *this; };
    

    另一种方法是使用能够执行“不需要的强制转换”的构造函数生成一个中间临时构造函数,您可以使用转换构造函数 explicit

    使用:

    explicit pint(int x){...}
    

    现在,编译器会给出一个错误!