为什么当输入是一个整数字面量时,编译器会忽略我的赋值运算符?

编程语言 2026-07-11

我原本预期的是 d = 5 会导致 operator=(5) 被执行,构造函数 derived(5) 不会参与其中。相反,执行了 derived(5),而 operator=(5) 没有被执行。

另外,cout 不会输出到bash,但在我在gdb中执行时会输出。

如何修复,使表达式 d = 5能导致 operator=(int x) 被执行,而不是构造函数 derived(int x)

# include <iostream>
# include <string>
using namespace std;
class base{
public:
   int y = 2;
   base() { cout << "base()"  << endl; }
}; // class base

class derived : public base {
public:
   int z = 1;
   derived(){ cout << "derived()"  << endl; }
   derived(int x) { z = x;   cout << "derived(int x)" << endl; }
   virtual int operator=(int& x) { cout << "z =" << to_string(z)  << endl;  return z;}
}; // class derived

int main() {
   derived d;
   d = 5;
}; // int main

cygwin 3.7.0
gdb 17.1-1
bash 5.2.21

解决方案

问题在于你为 derived 提供的赋值运算符的参数是一个类型为 int& 的非常量左值引用参数,它不能绑定到像 5 这样的右值。

但是由于你也提供了一个可转换构造函数 derived::derived(int),参数 5 可以通过这个可转换构造函数隐式转换为类型为 derived 的对象(因此得名)。为避免这种情况,你可以把这个可转换构造函数设为 explicit,这将禁止把 5 隐式转换为一个临时对象 derived。有关“在C++中何时将构造函数声明为explicit”的一些情形,请参阅 When to make constructor explicit in C++,其中列出像你这样的场景,在这些情形下 explicit 可以/应该 被使用。


如何修复

将赋值运算符的参数改为能够绑定到右值。你可以将其改为接受 const int&intconst int&int 将同时接受右值与左值作为参数。请注意,还有另一种接受右值的方式,即把参数的类型改为 int&&。这 int&& 仅接受右值,即如果传入左值,这第三种方式将不起作用(就你而言,三种方式都能工作)。

另见 When to make assignment operator virtual

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章