参考:

http://blog.csdn.net/rehongchen/article/details/7930853

http://blog.csdn.net/ming_road/article/details/6953687

http://blog.csdn.net/roden/article/details/5413371

中文版:p489 。对应英文版内容:

Like an inherited member function, the conversion from derived to base may or may not be accessible. Whether the conversion is accessible depends on the access label specified on the derived class' derivation.

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.

Regardless of the derivation access label, a public member of the base class is accessible to the derived class itself. Therefore, the derived-to-base conversion is always accessible to the members and friends of the derived class itself.

Tips:To determine whether the conversion to base is accessible, consider whether a public member of the base class would be accessible. If so, the conversion is accessible; otherwise, it is not.

提示:要确定到基类的转换是否可访问,可以考虑基类的public成员是否可访问,如果可以,转换是可以访问的,否则,转换是不可访问的。

首先要明白几个概念:用户代码(user code), 后代类(subsequently derived classes),派生类(derived class)

用户代码,指的是除友元函数,成员函数之外的代码。

后代类,不仅仅指第一级派生类,还包括间接派生自基类的后续的派生类。

派生类,这里专指直接继承类。

理解了上面的概念之后,通过代码来说明c++ primer中说到的4点。

class A
{
}; class B:public A
{
public:
void fun(B&obj)
{
A obj1 = (A)obj;
}
}; class C:protected A
{
public:
void fun(C&obj)
{
A obj1 = (A)obj;
}
}; class D:private A
{
public:
void fun(D&obj)
{
A obj1 = (A)obj;
}
}; class E:public B
{
public:
void fun(B&obj)
{
A obj1 = (A)obj;
}
}; class F:public C
{
public:
void fun(C&obj)
{
A obj1 = (A)obj;
}
}; //从private继承类派生的类不能转换为基类。
class H:public D
{
public:
void fun(D&obj)
{
A obj1 = (A)obj; //error C2247: “A”不可访问,因为“D”使用“private”从“A”继承
//error C2243: “类型转换”: 从“D *”到“const A &”的转换存在,但无法访问
}
};

用户代码中访问的内容:

void inherite_test()
{
A *pb, *pc, *pe, *pd, *pf, *ph; pb = new B; //public
pc = new C; //protected error C2243: “类型转换”: 从“C *”到“A *”的转换存在,但无法访问
pd = new D; //private error C2243: “类型转换”: 从“D *”到“A *”的转换存在,但无法访问
pe = new E; //public + public
pf = new F; //protected + public error C2243: “类型转换”: 从“F *”到“A *”的转换存在,但无法访问
ph = new H; //private + public error C2243: “类型转换”: 从“H *”到“A *”的转换存在,但无法访问
}

解析:

其中类B,C,D分别通过public,protected,private直接继承自A; 类E,F,H则分别public继承自B,C,D类。

各类的成员函数fun中进行派生类到基类的转换操作。

1、pb = new B;  B::fun,E::fun函数说明:

如果是public继承,则用户代码和后代类都可以使用派生类到基类的转换。

If the inheritance is public, then both user code and member functions of subsequently derived classes may use the derived-to-base conversion

2、inherite_test中C,D,F,H类转换的失败都说明了:

如果类是使用private或protected继承派生的,则用户代码不能将派生类型对象转换为基类对象。

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.

3、H类的fun函数发生的错误显示:

从private继承类派生的类不能转换为基类。

If the inheritance is private, then classes derived from the privately inherited class may not convert to the base class.

4、C::fun函数说明:

如果是protected继承,则后续派生类的成员可以转换为基类类型。

If the inheritance is protected, then the members of subsequently derived classes may convert to the base type.

有一点需要说明:对于多级派生的,要多个访问标号综合起来看可访问性。 有个简单的方法,见上面的tips.

例如,C 类protected继承自A,那么A中的public成员在C中变成了protected, F类public继承自C,这样在F中A的public成员fun函数为protected,是可见的。

所以F::fun中派生类到基类转换正确。

但是在用户代码中,是不能访问在C,F中变成了protected的A的public成员的,因此C,F对象转换为类A的对象出错。

=====>感觉fun函数定义的有点不合适,挺奇怪的,但是编译是没问题的,不知道现实生产中有没有这么用的??? (待定)

c++ primer 学习杂记2【派生类到基类转换的可访问性】的更多相关文章

  1. c++ primer 学习杂记1

    读到p483 公有,私有,受保护的继承. 1.关于基类成员在派生类中的访问级别: 1) 无论何种继承方式, 派生类都无法访问基类中的private成员. 2) 派生类可以限制,而不能放松对所继承成员的 ...

  2. c++ 派生类向基类转换的可访问性

    对于c++面向对象一直很疑惑,这次决定下功夫把它弄明白 一.派生类和基类之间的类型转换 首先理解,派生类含有基类的所有成分,只不过有些就算在派生类的成员函数也不能访问而已. (1)派生类和基类的自动转 ...

  3. 从零开始学C++之继承(二):继承与构造函数、派生类到基类的转换

    一.不能自动继承的成员函数 构造函数 析构函数 =运算符 二.继承与构造函数 基类的构造函数不被继承,派生类中需要声明自己的构造函数. 声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类 ...

  4. C++ 派生类到基类转换的可访问性

    今天看c++ primer关于派生类到基类转换的可访问性,看的很晕,看了下面的文章恍然大悟: http://www.2cto.com/kf/201403/283389.html C++ primer第 ...

  5. C#中派生类调用基类构造函数用法分析

    这里的默认构造函数是指在没有编写构造函数的情况下系统默认的无参构造函数 1.当基类中没有自己编写构造函数时,派生类默认的调用基类的默认构造函数例如: ? 1 2 3 4 5 6 7 8 9 10 11 ...

  6. 转 关于C#中派生类调用基类构造函数的理解

    关于C#中派生类调用基类构造函数的理解 .c#class       本文中的默认构造函数是指在没有编写构造函数的情况下系统默认的无参构造函数 1.  当基类中没有自己编写构造函数时,派生类默认的调用 ...

  7. c++中派生类对基类成员的三种访问规则(转)

    C++中派生类对基类成员的访问形式主要有以下两种:1.内部访问:由派生类中新增成员对基类继承来的成员的访问.2.对象访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问.今天给大家介绍在3中 ...

  8. c++——派生类和基类转换(类型兼容性原则)

    基类也叫父类,派生类也叫子类. 类之间的继承关系继承关系是类之间的父子关系. 继承关系的特点如下:A. 子类拥有父类的所有属性和行为B. 子类也是一种特殊的父类C. 子类对象可以当父类对象使用D. 子 ...

  9. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78516 ...

随机推荐

  1. JVM总结(六):早期(编译期)优化

    这节我们来总结一下JVM编译器优化问题. JVM编译器优化 Javac编译器 Javac的源码和调试 解析与填充符号表 注解处理器 语法分析与字节码生成 Java语法糖 泛型和类型擦除 自动装箱.拆箱 ...

  2. centos6.5环境下安装zk

    第一步:先下载安装包,解压. 第二步:进去根目录,创建data文件夹  mkdir  data 第三步:进去conf文件夹,修改  zoo_sample.cfg    的名字   mv zoo_sam ...

  3. javascript 利用冒泡机制显示与隐藏模态框

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  4. 单例设计模式Singleton之懒加载模式(懒汉模式)【原】

    单例设计模式Singleton之懒加载模式(懒汉模式) SingletonLazy.java类 package kingtool; import kingtool.http.IPTool; publi ...

  5. AtCoder Regular Contest 077 E - guruguru

    https://arc077.contest.atcoder.jp/tasks/arc077_c 有m个点围成一个圈,按顺时针编号为1到m,一开始可以固定一个位置x,每次操作可以往顺时针方向走一步或直 ...

  6. postgresql 常用速查

    中文资料 中文资料 /**gp中的基本sql语法**/ --删除表 drop table testtb; --创建表 CREATE TABLE testtb ( id integer, "n ...

  7. vue项目中安装使用echarts

    安装:cnpm install echarts -S (安装依赖并引入到 package.json) 官网安装说明:http://echarts.baidu.com/tutorial.html#%E5 ...

  8. 电脑爱好——PE系统分区工具 分区时函数错误,报000000001错误 解决方法

    1.启动硬盘分区软件diskgenius(一般都是这个分区软件,这个PE系统自带的居多) 2.将现有的分区全部删掉 3.选择菜单栏——“硬盘”——“转换分区表类型为MBR格式”——转换完成 4.快速分 ...

  9. static, const

    static 静态的,类的静态成员函数,静态成员变量是和类相关的,但不和具体对象相关.即使没有具体对象,也能调用类的静态成员函数和成员变量.一般类的静态函数就是一个全局函数,只是作用域在包含它的文件中 ...

  10. centOS7安装Composer

    1.进入Composer国内镜像网站文档页查看安装方法: https://docs.phpcomposer.com/00-intro.html 2.在centOS系统中进入特定目录执行以下命令: cd ...