我们知道,在类内的access specifier public 、protected、private都只是为了限定用户程序对类内的访问权限,而在继承list中的access specifier则是影响使用该derived类的用户对该类内的访问权限。public继承延续base部分的access specifier;protected继承则是把base public部分变成了protected,其余不变;private继承则是把所有base部分变成private。具体可以看primer p612 613的例子(english version)。

对于判断derived-to-base conversion是否legal,最重要的是该derived指针或base指针是否可以访问到base类中的public成员。这个准则实际上是为了保证让转换后的base指针可以像其他普通base指针一样可以访问应该可以访问得到的成员。这个判断准测与primer p613下面提出的3点是相匹配的。stackoverflow上有对此的讨论,我们结合它上面的代码来验证这个判断准则。

注意看注释!注释!注释!重要的事情说三遍...

 1 class B;
 2 class C;
 3 class D;
 4 class A{
 5     public:
 6         virtual ~A(){}
 7         friend void gg(D* d);
 8         void ga(B *b,C* c,D* d); int mem;
 9     };
10
11 class B:protected A{
12     public:
13         void gb(B *b,C* c,D* d);
14 };
15 class C:public B{};
16 class D:public C{};
17
18 void A::ga(B *b,C*c,D*d){
19     A *a1=b;  // error: 'A' is an inaccessible base of 'B' 原因:在A类中B类指针b无法访问base A部分的成员,即这里的b->mem是非法的(B是protected继承A),所以也就不能转换。
20     A *a2=c;  // error: 'A' is an inaccessible base of 'C' 原因同上,这里的c->mem也是非法的,因为mem在C类中是protected的。
21     A *a3=d;  // error: 'A' is an inaccessible base of 'D' 原因同上。
22 }
23 void B::gb(B *b,C*c,D*d){
24     A *a1=b;  // no problem here ,这里没问题是因为在类B中,b->mem是合法的。
25     A *a2=c;  //why do classes derived from B can sucessfully convert to A here? 这里c->mem是非法的,只有在类C或friend of class c中c->mem才合法。
26     A *a3=d;  //why do classes derived from B can sucessfully convert to A here? 原因同上
27 }
28 void gg(D* d){
29     A* a=d;  // 这里也会报错,同上
30 }
31 int main(){
32     B b;
33     C c;
34     D d;
35     A a;
36     gg(&d);  // error: 'A' is an inaccessible base of 'D'
37     a.ga(&b,&c,&d);
38     b.gb(&b,&c,&d);
39     A a1(d); //error here;Does it mean the implicit conversion in the user code is also user code?
40     A a4=d;  //same as above
41     return 0;
42 }

但是,下面那个例子打破了这个准则,问题在http://stackoverflow.com/questions/30524479/what-is-the-rationale-for-allowing-this-derived-to-base-conversion-when-it-seem 上。 根据里面的解释,我认为准则应该再加上primer中p614最顶端的那个条件:

member functions and friends of classes derived from D may use the d-to-b conversion if D inherits from B using either public or protected. Such code may not use the conversion if D inherits privately from B.

这就可以很好地解释下面那段代码了。

 1 class Base
 2 {
 3 public:
 4     int mem;
 5 };
 6
 7 class Derived : protected Base
 8 {
 9     static void f(Derived *d)
10     {
11         d->mem; // OK, in this context, a Derived IS-A Base
12         Base *b = d;
13     }
14 };
15
16 int main()
17 {
18     Derived d;
19     //d.mem;        // Compilation error : in this context a Derived IS-NOT-A Base
20     //Base *b = &d; // Compilation error too : consistent with the intuitive rule
21     return 0;
22 }
23
24 class Derived_Derived : public Derived
25 {
26     static void f(Derived *d)
27     {
28         //d->mem;    // Compilation error : in this context a Derived IS-NOT-A Base (as expected)
29         Base *b = d; // COMPILATION OK : which seems to violate the rule above
30     }
31 };

转载于:https://www.cnblogs.com/weili-wu/p/4861277.html

如何判断derived-to-base conversion是否legal相关推荐

  1. UVA10473 Simple Base Conversion【进制转换】

    In this problem you are asked to write a simplebase conversion program. You will be givena hexadecim ...

  2. POJ - 1220 NUMBER BASE CONVERSION(高精度运算+进制转换+模拟)

    题目链接:点击查看 题目大意:给出两个进制x和y,再给出一个x进制下的数num,求num转换为y进制后的答案 题目分析:直接套模板就行了,进制转换没什么好说的,直接模拟,这个题开了加速外挂只能优化几十 ...

  3. Java面试题18 牛客 假定Base b = new Derived();

    Java面试题18 牛客 假定Base b = new Derived(); 调用执行b.methodOne()后,输出结果是什么? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...

  4. java base class,Java; casting base class to derived class

    Why can't I cast a base class instance to a derived class? For example, if I have a class B which ex ...

  5. 求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)

    求1+2+3+-+n,要求不能使用乘除法.for.while.if.else.switch.case等关键字及条件判断语句(A?B:C) 文章目录 求1+2+3+...+n,要求不能使用乘除法.for ...

  6. 子类初始化列表不能初始化父类元素 -- class 'Derived' does not have any field named 'x'

    缘由 偶尔编写如下代码,编译出错, class Base{public:int x; };class Derived : public Base {public:Derived() : x(10) { ...

  7. 判断一个字符串是否经过base64加密过

    今天遇到一个判断数据库中密码是否为base64加密的密码,百度了半天也没找到判断办法,想了一会想到个小技巧,来给大家分享. 先对字符串进行解密,在对解密后的内容进行加密.如果加密后的内容和传过来的值相 ...

  8. C++ - 派生类(derived class) 的 构造(construct) 和 析构(destruct)顺序 详解

    派生类(derived class) 的 构造(construct) 和 析构(destruct)顺序 详解 本文地址: http://blog.csdn.net/caroline_wendy/art ...

  9. Think in Java第四版 读书笔记9第15章 泛型

    Think in Java第四版 读书笔记9第15章 泛型 泛型:适用于很多很多的类型 与其他语言相比 Java的泛型可能有许多局限 但是它还是有很多优点的. 本章介绍java泛型的局限和优势以及ja ...

最新文章

  1. gitlab更改默认Nginx
  2. 在Java中实现单例模式的有效方法是什么? [关闭]
  3. Fragment崩溃后重启
  4. 使用Chrome快速实现数据的抓取(四)——优点
  5. ElasticSearch之动态映射和模板
  6. Java主线程等待子线程、线程池
  7. 面试 - 要不简单聊一下你对MySQL索引的理解?
  8. html文字列表,文字列表模板
  9. spring-DataSource
  10. 《JS权威指南学习总结--6.1原型》
  11. 缓冲区溢出攻击-C语言中的危险函数
  12. 16.2互联网媒体信息讽刺识别
  13. 1 Vue的基础语法
  14. git pull origin拉取报错 Pulling without specifying how to reconcile divergent branches is
  15. 国密测试工具 GMProxy
  16. 转帖 美国 工程索引 收录中国科技论文的最新规定
  17. selenium 模拟浏览器刷新
  18. retina屏 适配问题
  19. 高德地图-添加自定义图标
  20. UITextField类对象左视图leftView无效--iOS开发

热门文章

  1. ssm整合2 增删改
  2. 文明重启服务器维护怎么卡进去,文明重启更新之后进不去,具体玩法介绍
  3. 算法训练 最长字符串 java
  4. ImportError: No module named setuptools 解决方法
  5. Hbase中的列式表映射到hive的外表
  6. 朴素贝叶斯(Naive Bayes),“Naive”在何处?
  7. scala把序列分解成子集(group by,partition)
  8. JVM内存参数设置及常见错误总结
  9. Attention的梳理、随想与尝试
  10. Java操作Hbase进行建表、删表以及对数据进行增删改查,条件查询