And*_*man 17 c++ inheritance abstract-class operator-keyword
我遇到了operator =的继承问题.为什么这段代码不起作用,解决它的最佳方法是什么?
#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;
}
Run Code Online (Sandbox Code Playgroud)
AnT*_*AnT 31
如果未在类中声明复制赋值运算符,编译器将隐式声明一个.隐式声明的复制赋值运算符将隐藏任何继承的赋值运算符(在C++中读取"名称隐藏"),这意味着任何继承的赋值运算符将对非限定名称查找过程变为"不可见" (当您这样做时会发生这种情况b = c) ,除非你采取具体步骤"取消隐藏"它们.
在您的情况下,类B没有显式声明的复制赋值运算符.这意味着编译器将声明
B& B::operator =(const B&)
Run Code Online (Sandbox Code Playgroud)
含蓄.它将隐藏继承的运算符A.这条线
b = c;
Run Code Online (Sandbox Code Playgroud)
不编译,因为,这里唯一的候选者是上面隐式声明的B::operator =(编译器已经告诉过你); 所有其他候选人都隐藏了.由于c不可转换B&,上述赋值不会编译.
如果您希望编译代码,可以使用using-declaration取消隐藏A::operator =通过添加继承的代码
using A::operator =;
Run Code Online (Sandbox Code Playgroud)
到了类的定义B.代码现在将编译,虽然它不是一个好的样式.您必须记住,在这种情况下,b = c将调用赋值A::operator =,它仅分配A所涉及对象的部分.(但显然这是你的意图.)
或者,在这种情况下,您始终可以使用名称的限定版本来解决名称隐藏问题
b.A::operator =(c);
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6012 次 |
| 最近记录: |