提问人:nuppigeller 提问时间:4/18/2020 最后编辑:templatetypedefnuppigeller 更新时间:4/19/2020 访问量:80
C++ 中运算符 = 的奇怪行为
Strange behaviour of operator= in C++
问:
我有一个基类 A 和两个派生类 B 和 C.B 定义 = 运算符,将基类 A 作为参数。
在类 B 上调用 = 时,有时会调用基类 A 的运算符,而不是 B 中的运算符。
class A {
public:
void operator=(A &) {
printf("A =\n");
};
};
class B : public A {
public:
void operator=(A &s) {
printf("B =\n");
};
};
class C : public A {
};
int main()
{
B b1, b2;
C c;
b1 = b2;
b1 = c;
}
输出为:
A =
B =
为什么第一个赋值不调用 B::operator=()?
为什么第二个赋值不调用 A::operator=(),因为它也是从 A 派生的?
我该怎么做才能让每次都调用 B::operator=()?
当我看到这个时,我感到非常惊讶。我注意到它只是因为我删除了 A 类中的 operator=() (“operator=() = delete”),导致编译器错误。
答:
10赞
Igor Tandetnik
4/18/2020
#1
您不是复制分配操作员。除了您提供的运算符之外,还有一个隐式定义的复制赋值运算符,该运算符等效于B::operator=
B& operator=(const B& other) {
A::operator=(other);
return *this;
}
此运算符不打印任何内容,但它调用基类上的赋值,并且该基类打印 .A=
b1 = b2
调用此复制赋值运算符。 调用 因为不是 .b1 = c
B::operator=(A&)
C
B
如果要调用运算符,请使用上面所示的签名定义一个复制分配运算符,而不是其他重载或作为其他重载的补充。
评论
0赞
nuppigeller
4/19/2020
这完全有道理,谢谢。我尝试了“B& operator=(const B&) = delete”来欺骗另一个运算符=(),但不幸的是这不起作用。但无论如何,有两个操作员并不是一个大问题。
0赞
Igor Tandetnik
4/19/2020
声明已删除的函数仍参与过载解析。如果实际选择了它,则程序的格式不正确。
评论
B::operator=
A
B