免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
123下一页
最近访问板块 发新帖
查看: 11067 | 回复: 20
打印 上一主题 下一主题

基类与继承类指针转换问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2005-11-21 10:10 |只看该作者 |倒序浏览
在Addison Wesley 出版的C++ FAQS, 2nd Edition中的FAQ 17.06中说:

Q:Can a derived class pointer be converted into a pointer to its public base class?
A:Such conversions are possible and don't even require a pointer cast.

class Vehicle { };
class Car : public Vehicle { };

void f(Vehicle* v) throw();

void g(Car* c) throw()
{
  f(c);  //Perfectly safe; no cast needed
}

而在侯捷的深入浅出MFC中第二章C++重要性质中:
1、如果你以一个"基类之指针"指向一个"派生类之对象",那么经由该指针你只能调用该基类所定义的函数
2、如果你以一个“派生类之指针”指向一个“基类之对象”,你必须先做明显的转型操作(explicit cast),这种作法很危险,不符合真实生活经验,在设计上也许会带给程序员困惑;
3、如果积累和派生类都定义了“相同名称之函数”,那么通过对象指针调用成员函数时,到底调用了那个函数,必须视该指针的原始类型而定,而不是视指针实际所指的对象的类型而定,这与第1点其实意义相通。

深入浅出中的2与C++ FAQS的说法应该矛盾的吧,请高手指教。谢谢

[ 本帖最后由 gp101224 于 2005-11-21 10:11 编辑 ]

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
2 [报告]
发表于 2005-11-21 10:22 |只看该作者
Q:Can a derived class pointer be converted into a pointer to its public base class?

“派生类之指针指向一个“基类之对象”,

[ 本帖最后由 gvim 于 2005-11-21 10:23 编辑 ]

论坛徽章:
0
3 [报告]
发表于 2005-11-21 10:27 |只看该作者

似乎是你对侯捷的话理解有误

结合你的例子
1。 以一个"基类之指针"指向一个"派生类之对象",
基类之指针:Vehicle* pVehicle
派生类之对象: Car* pCar=new Car();
指向:pVehicle=pCar;不需要任何显式转换

2、如果你以一个“派生类之指针”指向一个“基类之对象”
派生类之指针:Car* pCar
基类之对象:Vehicle *pVehicle=new Vehicle()
指向:pCar=(Car*)pVehicle;需要显式转换,而且会带来很多不可预知因素

论坛徽章:
0
4 [报告]
发表于 2005-11-21 10:39 |只看该作者
两者并没有矛盾,只是你误认为两者是相同的情况~~

C++中,继承类一般都要比基类含有更多的成员,比方说:

  1. class a
  2. {
  3.     int m;
  4. };

  5. class b : public a
  6. {
  7.     int n;
  8. };
复制代码

此时b中除了含有m之外,还有自己的类成员n.所以使用基类指针指向继承类对象是安全的,因为基类的成员都会出现在继承类中,反之不成立,这就解释了MFC中的1,2点.但是,你需要注意的是:这里的1,2说的都是指针指向对象,而不是指针之间的相互转换~~

FAQ里指的是指针之间的转换,继承类的指针转换成基类的指针当然是安全的,原因如上;但是具体在使用基类和继承类指针时会调用哪个类成员的函数,这个在MFC中说的第3点并不完全的准确,还要涉及到函数是不是虚拟函数,重载(overload),覆盖(override)等概念~~
你可以看看:
http://bbs.chinaunix.net/viewthread.php?tid=643467&fpage=1&highlight=

论坛徽章:
0
5 [报告]
发表于 2005-11-21 10:49 |只看该作者
原帖由 converse 于 2005-11-21 10:39 发表
两者并没有矛盾,只是你误认为两者是相同的情况~~

C++中,继承类一般都要比基类含有更多的成员,比方说:

  1. class a
  2. {
  3.     int m;
  4. };

  5. class b : public a
  6. {
  7.     int n;
  8. };
复制代码

此时b中除了含 ...


可能是我误解了,我想写书的不至于把基础概念给搞错了,好好看看再说

论坛徽章:
0
6 [报告]
发表于 2005-11-21 10:55 |只看该作者
原帖由 gp101224 于 2005-11-21 10:49 发表


可能是我误解了,我想写书的不至于把基础概念给搞错了,好好看看再说


简单的说吧:FAQ里面指的是指针和指针之间的转换,而MFC中的1,2指的是指针指向对象的时候的情况,你好好体会一下吧,写一些小的测试程序感受一下~~

论坛徽章:
0
7 [报告]
发表于 2005-11-21 11:04 |只看该作者
原帖由 gp101224 class Vehicle { };
class Car : public Vehicle { };

void f(Vehicle* v) throw();

void g(Car* c) throw()
{
  f(c);  //Perfectly safe; no cast needed
}



这相当于 把基类的指针指向一个派生类,就是 侯说的第一种情况。

论坛徽章:
0
8 [报告]
发表于 2005-11-21 11:13 |只看该作者
原帖由 win_hate 于 2005-11-21 11:04 发表



这相当于 把基类的指针指向一个派生类,就是 侯说的第一种情况。


不是这样的,候sir指的是:1、如果你以一个"基类之指针"指向一个"派生类之对象",那么经由该指针你只能调用该基类所定义的函数

候sir指的是指针指向对象的情况,而FAQ里面说的是指针之间的转换....在C++中,可以通过基类指针操作继承类函数的,这个就是所谓的多态....

[ 本帖最后由 converse 于 2005-11-21 11:15 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2005-11-21 11:20 |只看该作者

  1. void f(Vehicle* v) throw();

  2. void g(Car* c) throw()
  3. {
  4.   f(c);  //Perfectly safe; no cast needed
  5. }
复制代码


type A  指针指向一个 type B 对象本质上就是两种指针的转换,是吗?

在上面的代码中,假定 g 被调用时 c 指向了一个 Car 类对象 C, 则 f(c) 中 c 被看成 Vehicle 类指针,指向一个 Car 类对象。

论坛徽章:
2
亥猪
日期:2014-03-19 16:36:35午马
日期:2014-11-23 23:48:46
10 [报告]
发表于 2005-11-21 11:25 |只看该作者
原帖由 win_hate 于 2005-11-21 11:20 发表

  1. void f(Vehicle* v) throw();

  2. void g(Car* c) throw()
  3. {
  4.   f(c);  //Perfectly safe; no cast needed
  5. }
复制代码


type A  指针指向一个 type B 对象本质上就是两种指针的转换,是吗?

在上面 ...


Car* c 和 Vehicle* v , 都是声明成指针.
如果是指针和对象,大概是这样:
type b;
type *a = &b;
这样才是候sir的说明a 是指针 b是对象.
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP