为什么孙子类的指针可以强行转换为祖父类的

liuzu2016 2012-09-27 08:53:00

HRESULT B: QueryInterface(const IID& iid, void** ppv)
{
if(iid==IID_IUnkown)
{
*ppv=(IUnkown*)this; //转换(1) ,孙子类指针转换为祖父类指针
((IUnkown*)(*ppv)->AddRef();
}
else if(iid==IID_OtherInterface)
{
*ppv=(IOtherInterface*)this; //转换是否多余 (2)
((IOtherInterface*)(*ppv)->AddRef();

}
else if(iid== IID_SomeInterface)
{
return m_pUnkownInner->QueryInterface(iid,ppv);
}
else
{
*ppv=NULL;
return E_NONTERFACE;
}
return S_OK;
}


(1)为什么孙子类的指针可以强行转换为祖父类的, 我记得,只可以转换为父亲类的指针吧?

(2) 转换为父亲类的指针后,由于是虚函数,最终还是调用孙子类的 覆盖的虚函数, 所以 对于转换为(2)是否多余?
...全文
231 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
Coder_Y_Jao 2012-09-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]
没听说过, 是祖父类的指针去调用 祖父类中的虚函数(前提: 孙子类已经覆盖了虚函数, 而父亲类可以覆盖也可以不覆盖)。

也就说,祖父类指针不能够调用到 孙子或者孙子类以下的 辈分的 虚函数,只能跨越到父亲类!
[/Quote]

在COM的接口及实现中不存在你说得情况,因为COM不支持实现继承。
换句话说,你的孙子类的父亲和祖父等等都是接口,是纯虚基类,他们当中是没有任何实现的,而孙子类则必须实现,所以唯一不支持子孙类到祖父类的情况是:多继承(菱形继承)(COM中多继承是非虚拟继承的)
liuzu2016 2012-09-27
  • 打赏
  • 举报
回复
多谢,昨晚 我查了 资料,重新阅读多态。 我是这么理解的:

多态: 是 父亲类指针调用 父亲类中的虚函数或者其继承来的虚函数

有两种方式:

(1) 父亲类、祖父类都没有覆盖某虚函数, 而有2个孙子类覆盖该虚函数了,所以实现了多态。

根据该指针指向的哪一个孙子!


(2) 祖父类或者父亲类 覆盖了虚函数, 有一个孙子类也覆盖而来, 然后用父亲类的指针去调用该虚函数,

那么 得到的结果可能是 父亲类的(可能是父亲类自身覆盖的,也可能是继承来的), 或者孙子类的。

这种也算是多态!





没听说过, 是祖父类的指针去调用 祖父类中的虚函数(前提: 孙子类已经覆盖了虚函数, 而父亲类可以覆盖也可以不覆盖)。

也就说,祖父类指针不能够调用到 孙子或者孙子类以下的 辈分的 虚函数,只能跨越到父亲类!






[Quote=引用 4 楼 的回复:]

你之前的帖子中2楼我已经给你回复了
http://topic.csdn.net/u/20120926/12/14257a8e-072e-4595-8d99-4d36cb96202d.html
[/Quote]
Coder_Y_Jao 2012-09-27
  • 打赏
  • 举报
回复
你之前的帖子中2楼我已经给你回复了
http://topic.csdn.net/u/20120926/12/14257a8e-072e-4595-8d99-4d36cb96202d.html
sophistcxf 2012-09-27
  • 打赏
  • 举报
回复
你考虑这样的情况:
Base有两个子类A和B,A有A::f1(),B有B::f2(),但这两个函数在Base中都没虚函数,而另有一个函数返回一个Base*,这个Base*的实例可以是A也可以是B,你不强转的话,怎么拿返回的这个Base*调用A::f1或者B::f2。
冷月清晖 2012-09-27
  • 打赏
  • 举报
回复
不多余啊,关键逻辑要通顺,iid是判断依据。
liuzu2016 2012-09-27
  • 打赏
  • 举报
回复
FrankHB1989 2012-09-27
  • 打赏
  • 举报
回复
1.不是语法问题。
2.LS已经说了。
引用
没听说过, 是祖父类的指针去调用 祖父类中的虚函数(前提: 孙子类已经覆盖了虚函数, 而父亲类可以覆盖也可以不覆盖)。

也就说,祖父类指针不能够调用到 孙子或者孙子类以下的 辈分的 虚函数,只能跨越到父亲类!

这个是错的。若父亲类和孙子类都覆盖了,祖父类指针可以调用孙子类的虚函数。
另外注意覆盖不等于显式virtual,如果签名和直接或间接基类有相同且这个基类里的函数声明有virtual,那么派生类相同(或仅有返回类型不同但协变)签名的函数也是虚函数,视为覆盖了基类的。
一句话,认准签名,顺着继承树自顶向下找某个虚函数的final overrider是什么,不用考虑每一层具体是谁覆盖了谁。

64,266

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧