C++ 中 operator= 的继承问题 [英] Trouble with inheritance of operator= in C++
问题描述
我在继承 operator= 时遇到问题.为什么此代码不起作用,修复它的最佳方法是什么?
I'm having trouble with the inheritance of operator=. Why doesn't this code work, and what is the best way to fix it?
#include <iostream>
class A
{
public:
A & operator=(const A & a)
{
x = a.x;
return *this;
}
bool operator==(const A & a)
{
return x == a.x;
}
virtual int get() = 0; // Abstract
protected:
int x;
};
class B : public A
{
public:
B(int x)
{
this->x = x;
}
int get()
{
return x;
}
};
class C : public A
{
public:
C(int x)
{
this->x = x;
}
int get()
{
return x;
}
};
int main()
{
B b(3);
C c(7);
printf("B: %d C: %d B==C: %d
", b.get(), c.get(), b==c);
b = c; // compile error
// error: no match for 'operator= in 'b = c'
// note: candidates are B& B::operator=(const B&)
printf("B: %d C: %d B==C: %d
", b.get(), c.get(), b==c);
return 0;
}
推荐答案
如果你没有在类中声明复制赋值运算符,编译器会为你隐式声明一个.隐式声明的复制赋值运算符将隐藏任何继承的赋值运算符(阅读 C++ 中的名称隐藏"),这意味着任何继承的赋值运算符将对 未限定变得不可见"em> 名称查找过程(当您执行 b = c
时会发生这种情况),除非您采取特定步骤取消隐藏"它们.
If you do not declare copy-assignment operator in a class, the compiler will declare one for you implicitly. The implicitly declared copy-assignment operator will hide any inherited assignment operators (read about "name hiding" in C++), meaning that any inherited assignment operators will become "invisible" to the unqualified name lookup process (which is what happens when you do b = c
), unless you take specific steps to "unhide" them.
在您的情况下,B
类没有明确声明的复制赋值运算符.这意味着编译器会声明
In your case, class B
has no explicitly declared copy-assignment operator. Which mean that the compiler will declare
B& B::operator =(const B&)
隐含的.它将隐藏从 A
继承的操作符.线
implicitly. It will hide the operator inherited from A
. The line
b = c;
不编译,因为这里唯一的候选对象是上面隐式声明的 B::operator =
(编译器已经告诉你了);所有其他候选人都是隐藏的.由于 c
不能转换为 B&
,上面的赋值不能编译.
does not compile, because, the only candidate here is the above implicitly declared B::operator =
(the compiler told you about that already); all other candidates are hidden. And since c
is not convertible to B&
, the above assignment does not compile.
如果你想让你的代码编译,你可以使用 using-declaration 通过添加
If you want your code to compile, you can use using-declaration to unhide the inherited A::operator =
by adding
using A::operator =;
到B
类的定义.代码现在可以编译了,尽管它不是一个好的样式.你必须记住,在这种情况下,b = c
赋值将调用 A::operator =
,它只分配 A
部分所涉及的对象.(但显然这是你的意图.)
to the definition of class B
. The code will now compile, although it won't be a good style. You have to keep in mind that in this case the b = c
assignment will invoke A::operator =
, which assigns only the A
portions of the objects involved. (But apparently that is your intent.)
或者,在这种情况下,您始终可以通过使用名称的 限定 版本来解决名称隐藏问题
Alternatively, in cases like this you can always work around name hiding by using a qualified version of the name
b.A::operator =(c);
这篇关于C++ 中 operator= 的继承问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!