max*_*yne 38 c++ inheritance compiler-errors
这是一个面试问题.考虑以下:
struct A {};
struct B : A {};
A a;
B b;
a = b;
b = a;
Run Code Online (Sandbox Code Playgroud)
为什么b = a;
抛出错误,虽然a = b;
完全没问题?
Joh*_*itb 62
因为隐式声明的复制赋值运算符B
隐藏了隐式声明的复制赋值运算符A
.
所以对于线b = a
,只有在operator=
的B
是一个候选人.但是它的参数有类型B const&
,不能通过A
参数初始化(你需要一个向下转换).所以你得到一个错误.
use*_*016 24
因为每个B都是A,但不是每个A都是B.
编辑以下评论以使事情更清楚(我修改了你的例子):
struct A {int someInt;};
struct B : A {int anotherInt};
A a;
B b;
/* Compiler thinks: B inherits from A, so I'm going to create
a new A from b, stripping B-specific fields. Then, I assign it to a.
Let's do this!
*/
a = b;
/* Compiler thinks: I'm missing some information here! If I create a new B
from a, what do I put in b.anotherInt?
Let's not do this!
*/
b = a;
Run Code Online (Sandbox Code Playgroud)
在你的榜样,没有属性someInt
,也没有anotherInt
,所以它可以工作.但无论如何编译器都不会允许它.
确实a B
是a A
,但是a A
不是a B
,但是当你使用指针或对A
s和B
s的引用时,这个事实才直接适用.这里的问题是你的赋值运算符.
struct A {};
struct B : A {};
Run Code Online (Sandbox Code Playgroud)
相当于
struct A {
A& operator=(const A&);
};
struct B : A {
B& operator=(const B&);
};
Run Code Online (Sandbox Code Playgroud)
所以当你在下面分配时:
A a;
B b;
a = b;
Run Code Online (Sandbox Code Playgroud)
a
可以使用参数of来调用赋值运算符on b
,因为a B
是a A
,因此b
可以作为a传递给赋值运算符A&
.请注意,a
赋值运算符只知道a中的数据,A
而不知道a中的东西B
,因此B中不属于A的任何成员都会丢失 - 这称为"切片".
但是当你试图分配时:
b = a;
Run Code Online (Sandbox Code Playgroud)
a
是类型A
,不是a B
,因此a
无法将B&
参数与b
赋值运算符匹配.
你会认为b=a
应该只调用继承A& A::operator=(const A&)
,但事实并非如此.赋值运算符B& B::operator=(const B&)
隐藏了将继承的运算符A
.它可以通过using A::operator=;
声明再次恢复.
归档时间: |
|
查看次数: |
1561 次 |
最近记录: |