X1n4n 发表于 2012-11-14 10:28:36

【面试题】C++虚函数的一个有意思的小代码

#include <iostream>

using namespace std ;

class A
{
public:
virtual void show()
{
cout << "Show in A" << endl ;
}
} ;

class B
{
public:
virtual void matrix()
{
cout << "matrix" << endl ;
}
virtual void show()
{
cout << "Show in B" << endl ;
}
} ;


int main()
{
//
// Guess what will be printed before you run it
// And why ?
//
A *p = (A *)(new B) ;
p->show() ;

return 0 ;
}
运行前猜猜结果??

hslx111 发表于 2012-11-14 11:59:53

原来猜是“Show in B",后来试了一下是”matrix“就知道自己想的不对了。
然后查了一下虚函数的使用,编译器在处理虚函数时,是对每个对象添加一个隐藏成员,隐藏成员中保存了一个指向函数地址数组的指针。这样一说就明白了。
p是一个A类型的指针对象,所以p->show指向的是虚函数地址数组的首地址,但是new B也就是说这个说p->show指向的是B类虚函数地址数组的首地址,从B类的定义可以知道,首地址存的是matrix()虚函数,所以会执行cout << "matrix" << endl ;

X1n4n 发表于 2012-11-14 13:16:05

楼上和楼上的点评都对了~~哈 就是 vtable ...
那么我再追加一问:

假设 B 类的定义中是这样的:

class B : public A
{ .....

其余全部一样,问结果是什么样的?
再从vtable的角度考虑怎么解释?
回答了这个我想您就会理解多态究竟怎么实现的。。。{:6_194:}

欢迎各位童鞋踊跃抢答啊~

ant_qingyun27sc 发表于 2012-11-14 13:30:49

X1n4n 发表于 2012-11-14 13:16 static/image/common/back.gif
楼上和楼上的点评都对了~~哈 就是 vtable ...
那么我再追加一问:



B继承A,show()方法在运行时多态,main函数中,p指向的是实际上是B,p->show()自然就是B的show()了。从VTABLE的角度,我觉得是多态机制在运行时,会选择是用A还是B的VTABLE,再根据选择的VTABLE去调用虚函数,不知道是不是这样

ant_qingyun27sc 发表于 2012-11-14 13:33:12

还有一个疑问,就是为什么最初那段A和B没有继承关系的那段代码里,A *p = (A *)(new B) ;这样的强制转换会通过呢?不懂

hslx111 发表于 2012-11-14 16:43:42

ant_qingyun27sc 发表于 2012-11-14 13:33 static/image/common/back.gif
还有一个疑问,就是为什么最初那段A和B没有继承关系的那段代码里,A *p = (A *)(new B) ;这样的强制转换会通 ...

new B是在内存中分配了B大小的内存并返回首地址指针,(A *)就是强制将这个指针看做是指向A的一个指针,也就是说内存里存的是B,但是系统以为是A.

ant_qingyun27sc 发表于 2012-11-14 17:40:53

hslx111 发表于 2012-11-14 16:43 static/image/common/back.gif
new B是在内存中分配了B大小的内存并返回首地址指针,(A *)就是强制将这个指针看做是指向A的一个指针,也 ...

{:6_196:}这年头,干啥都不容易。灌水也要专业点吧。除了几个表情,你就不再说点啥么?请多写几个字再提交。

sbb3315 发表于 2012-11-14 21:13:27

这个题还算有趣啊,我还重来没这么思考过,以为虚函数存在就是为了实现多态,以为单独声明会报错呢。。。不过这个有必要用虚函数来写么?
页: [1]
查看完整版本: 【面试题】C++虚函数的一个有意思的小代码