PAYATHON 2026

为什么 d = 5 没有调用 operator=(int)?

数据小许

结论

5 是整数字面量,属于右值,不能绑定到 int&。因此,operator=(int& x) 不适用于 d = 5。由于 derived(int) 可以将 5 隐式转换为 derived,编译器会使用隐式生成的 operator=(const derived&),把转换得到的临时对象赋给 d。这个过程会调用 derived(int) 来构造临时对象,但不会调用你定义的 operator=(int&)。

将赋值运算符的参数改为按值接收的 int,d = 5 就能匹配这个重载。

修改赋值运算符

derived& operator=(int x) {
    z = x;
    cout << "z =" << to_string(z) << endl;
    return *this;
}

这样,d = 5 会调用 operator=(int),并将 d.z 设为 5。原来的函数只输出 z 并返回它,没有把参数 x 赋给成员 z。要让赋值生效,需要像上面这样写 z = x。

这个赋值运算符不需要声明为 virtual。关键在于参数类型能否接收右值 5。

为什么原代码会调用构造函数

原定义是:

virtual int operator=(int& x) { ... }

int& 是非常量左值引用,不能绑定到整数字面量 5。不过,derived(int x) 允许从 int 隐式构造 derived 对象。因此,d = 5 可以先构造一个临时 derived 对象,再调用编译器隐式生成的复制赋值运算符。构造临时对象时,会打印 base() 和 derived(int x)。

改为 operator=(const int& x) 也能接收右值。对于简单的整数参数,通常写成 operator=(int x) 更直接。

bash 下没有输出

代码中的 endl 会换行并刷新 cout 缓冲区。仅凭这段代码,无法确定 bash 下没有输出的具体原因。程序在 gdb 和 bash 中运行时,标准输出可能连接到不同的终端,也可能被重定向。可以在 bash 中检查实际运行的可执行文件,并确认输出没有被重定向,例如:

./program.exe
./program.exe >output.txt 2>&1

第二条命令会把标准输出和标准错误写入 output.txt,可以用来判断程序是否有输出,只是被终端或启动方式隐藏了。由于没有提供实际运行命令及其输出目标,无法进一步确定环境方面的原因。

备注:内容仅供参考。