我在上课时遇到了这种好奇心
#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
为什么:
答案 0 :(得分:5)
这里有趣的是,你不仅有一个物体!你会产生一些临时的。
*x1 = 8;
类引脚没有operator=(int)
,但它可以通过int生成一个pint对象。因此调用构造函数pint(int)
。现在可以将具有新地址的新对象提供给operator(const pint&)
这就是你看到“set1”文字的原因。 “8”将首先创建一个临时品脱对象,该对象具有新地址。
如果添加以下内容,“魔法”就会消失:
pint& operator = (const int a) { std::cout << "set 3. >> " << this << " | a >> " << &a << std::endl; return *this; };
另一种看到你的编译器使用能够执行“不需要的转换”的构造函数生成中间临时的方法,你可以创建转换构造函数explicit
。
使用:
explicit pint(int x){...}
现在你的编译器会给你一个错误!