找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 2434|回复: 3

派生类对象到基类转换的可访问性

[复制链接]

33

主题

1

回帖

561

积分

用户组: 大·技术宅

UID
580
精华
26
威望
28 点
宅币
341 个
贡献
0 次
宅之契约
0 份
在线时间
8 小时
注册时间
2014-12-8
发表于 2015-1-15 18:25:51 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

×
C++ primer第四版15.3小节有这样一段话:

如果是 public 继承,则用户代码和后代类都可以使用派生类到基类的转换。如果类是使用 private 或 protected 继承派生的,则用户代码不能将派生类型对象转换为基类对象。如果是 private 继承,则从 private 继承类派生的类不能转换为基类。如果是 protected 继承,则后续派生类的成员可以转换为基类类型。

看完后感觉一团雾水,后来看英文原版中这样写:

If the inheritance is public, then both user code and member functions of subsequently derived classes may use the derived-to-base conversion. If a class is derived using private or protected inheritance, then user code may not convert an object of derived type to a base type object. If the inheritance is private, then classes derived from the privately inherited class may not convert to the base class. If the inheritance is protected, then the members of subsequently derived classes may convert to the base type.

这样写我们就清楚多了。为了更明白的说明问题,我们构造三个类A,B,C。A是base类。B继承于A,C继承于B。
现在我们要说明的问题有两个,一个是用户代码中访问的问题,一个是派生类中访问的问题。

(1)先说用户代码中访问的问题。
B和A的关系有三种:
1        B:public    A
2        B:proteced  A
3        B:private   A

针对这样一段代码:
A a;
B b;
a = b;
我们把它放在main.cpp中时,只有1是正确的,2,3都是错误的。这个说明的就是:只有当子类和基类的关系是public继承时,才能在用户代码中把子类赋给基类,其余两种都不行。

(2) 后继派生类中访问的问题
C和B的关系有三种
1        C:public    B
2        C:proteced  B
3        C:private   B
但是不管C和B关系怎样,C中总是可以访问B的public和protected成员,现在假设C中有一个成员函数
void  C::func()
{
A a;
B b;
a = b;
}
此时当B和A的关系是public,protected继承的时候,函数func的这段代码都没有问题,因为A,B中的非private成员在C中都可以为访问,所以没有问题。但是当B和A的关系是private的时候,这段代码就出问题了,因为A在B中是私有成员,所以不能访问A,更不用说 a = b了。
回复

使用道具 举报

0

主题

10

回帖

85

积分

用户组: 小·技术宅

UID
513
精华
0
威望
1 点
宅币
73 个
贡献
0 次
宅之契约
0 份
在线时间
13 小时
注册时间
2014-10-9
发表于 2015-1-15 18:46:43 | 显示全部楼层
本帖最后由 ganboing 于 2015-1-15 18:48 编辑

这个在有虚继承+虚函数的时候会更复杂一些,因为从基类到派生类会有不止一条路径
比如

class A { virtual ~A(); {} };
class B : virtual private A {};
class C : virtual public A {};
class D : public B, public C {};

//      A
//     / \
//    B   C
//     \ /
//      D

这时如果
dynamic_cast<A*>((B*)new D);

那么转换还是会成功,因为upcast B->A虽然转换失败,但是cross-cast B->D->C->A转换成功(有运行时检查的情况下)
回复 赞! 靠!

使用道具 举报

307

主题

228

回帖

7349

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5599 个
贡献
253 次
宅之契约
0 份
在线时间
949 小时
注册时间
2014-1-25
发表于 2015-1-15 19:57:26 来自手机 | 显示全部楼层
这是某个头文件里的,,,
回复 赞! 靠!

使用道具 举报

0

主题

10

回帖

85

积分

用户组: 小·技术宅

UID
513
精华
0
威望
1 点
宅币
73 个
贡献
0 次
宅之契约
0 份
在线时间
13 小时
注册时间
2014-10-9
发表于 2015-1-15 20:32:03 | 显示全部楼层
元始天尊 发表于 2015-1-15 19:57
这是某个头文件里的,,,

vc的crt代码里注释中的例子
回复 赞! 靠!

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-5-4 23:46 , Processed in 0.041483 second(s), 32 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表