在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\n", 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\n", b.get(), c.get(), b==c);
return 0;
}
推荐答案
- 在类中的赋值运算符,编译器将为您隐式声明一个。隐式声明的复制赋值操作符将隐藏任何继承的赋值操作符(读取C ++中的名称隐藏),意味着任何继承的赋值操作符对于不合格名称查找过程(这是当您执行 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屋!