下面这个C++代码为什么输出y y1而不是y x1呢?为什么和直接调z->xx()的结果不同?
#include <iostream>
using namespace std;
class a {
public:
void virtual x() {
cout << "x" << endl;
}
void xx() {
cout << "x1" << endl;
}
};
class b :public a {
public:
void x() {
cout << "y" << endl;
xx();
}
void xx() {
cout << "y1" << endl;
}
};
int main()
{
b b1;
a* z = &b1;
z->x();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
和"動態邊編"無關. 這裏的問題只是name hiding導致的罷了.
因爲這是在標準文檔中有着明確規定的.
§ 6.3.10
需要注意的是這裏只要求的
name
, 不要求signature
, 那麼讓我們來看這份代碼,clang告訴我們在
b
中是看不到a
中的void xx(int)
. 爲什麼呢? 就是因爲上面所說的, 同時滿足了兩個條件:name
.a
和b
中出現所以結果就是
hides the declaration
.好, 我們來坐下實驗, 因爲這兩個條件要同時滿足, 即成交集, 如果我們破壞了第二個條件, 把
b
中的xx
函數移除, 那麼這個hiding
會怎麼樣呢? 理論上就會消失, 到底是不是呢?果然通過編譯並且正確輸出了.
这是属于动态联编的问题,可以百度学习一下
实现动态联编的条件:
(1)公有继承
(2)调用虚函数
(3)通过基类的对象指针或者对象的引用调用虚函数
在你的代码中z是一个基类指针,指向了一个子类对象,并且z调用的函数x()是一个虚函数,所以发生了动态联编,调用的是b1的x()函数,在这个函数中又调用了xx()函数,此函数与基类中的xx()函数重名,所以基类的xx()函数被隐藏了,所以不论xx()函数是否为虚函数,调用的始终是b1自己的。
使用z去调用xx()函数,由于xx()函数不是虚函数,不满足动态联编的条件,所以不发生动态联编,因而调用的是基类中的xx()函数