为什么当输入是一个整数字面量时,编译器会忽略我的赋值运算符?
我原本预期的是 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& 或 int。const int& 与 int 将同时接受右值与左值作为参数。请注意,还有另一种接受右值的方式,即把参数的类型改为 int&&。这 int&& 仅接受右值,即如果传入左值,这第三种方式将不起作用(就你而言,三种方式都能工作)。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。