问题1:子类B可以有3种方式(public, protected, private)继承父类A,用哪种方式继承,用户代码才能把子类B的对象转换成父类A的对象呢?

只用当子类B以public方式继承父类A后,在用户代码里,才能把子类B的对象转换成父类A的对象。

原因如下:

  • 下面例子的类Pro_derv和类Pri_derv,分别是以protected和 private的方式继承了Base,所以在类Pro_derv和类Pri_derv对象里,原来在Base类里的成员pub_mem()已经不是public的属性了,而分别是protected和 private的属性了,protected和 private属性的成员对于用户程序来说是不可访问的。
  • 当创建了Pro_derv和类Pri_derv的对象后,成员pub_mem()已经是分别是protected和 private的属性了。所以类Pro_derv和类Pri_derv的用户程序是不可以访问protected或者 private属性的成员pub_mem()的。
  • 当要把类Pro_derv和类Pri_derv的对象转换成父类Base类的对象的时候,从类Base的角度看,pub_mem()是public的成员,所以类Base的用户程序是可以访问pub_mem()的,但是从类Pro_derv和类Pri_derv的角度看,pub_mem()已经不是public的成员了,所以类Pro_derv和类Pri_derv的用户程序是不可以访问成员pub_mem()的。这时,编译器就很困惑这个矛盾了,所以编译器干脆就不让你编译通过。。。
class Base{
public:
void pub_mem();
protected:
int prot_mem;
private:
char pri_mem;
}; class Pub_derv : public Base{
int f(){
pub_mem();
return prot_mem;
}
//char g(){return pri_mem;}//error
}; class Pro_derv : protected Base{
int f(){
pub_mem();
return prot_mem;
}
//char g(){return pri_mem;}//error
}; class Pri_derv : private Base{
int f(){
pub_mem();
return prot_mem;
}
}; int main(){
Pub_derv pub;
Pro_derv pro;
Pri_derv pri; Base& b1 = pub;
Base& b2 = pro;//error
Base& b3 = pri;//error
}

github

问题2:子类B可以有3种方式(public, protected, private)继承父类A,用哪种方式继承,在子类B的成员函数和子类B的友元(非用户代码)里才能把子类B的对象转换成父类A的对象呢?

不论子类B以何种方式继承父类A,在子类B的成员函数和子类B的友元里(非用户代码),都能把子类B的对象转换成父类A的对象。

原因如下:

- 不论子类B以何种方式继承父类A,在子类B的成员函数和子类B的友元(非用户代码)里,父类A的所以成员的属性是不发生变化的,所以转化后,还是可以用父类A的对象,访问父类A的public成员。

class Base{
public:
void pub_mem();
protected:
int prot_mem;
private:
char pri_mem;
}; class Pub_derv : public Base{
int f(){
pub_mem();
return prot_mem;
}
//char g(){return pri_mem;}//error
}; class Pro_derv : protected Base{
friend void pro_fri(Pro_derv&);
int f(){
Base& b = *this;//不论子类B以何种方式继承父类A,在子类B的成员函数和子类B的友元(非用户代码)里,都能把子类B的对象转换成父类A的对象。
pub_mem();
return prot_mem;
}
//char g(){return pri_mem;}//error
}; class Pri_derv : private Base{
friend void pri_fri(Pri_derv&);
int f(){
Base& b = *this;//不论子类B以何种方式继承父类A,在子类B的成员函数和子类B的友元(非用户代码)里,都能把子类B的对象转换成父类A的对象。
pub_mem();
return prot_mem;
}
}; void pro_fri(Pro_derv& pro){
Base& b = pro;//不论子类B以何种方式继承父类A,在子类B的成员函数和子类B的友元(非用户代码)里,都能把子类B的对象转换成父类A的对象。
} void pri_fri(Pri_derv& pro){
Base& b = pro;//不论子类B以何种方式继承父类A,在子类B的成员函数和子类B的友元(非用户代码)里,都能把子类B的对象转换成父类A的对象。
}
int main(){
Pub_derv pub;
Pro_derv pro;
Pri_derv pri; Base& b1 = pub;
//Base& b2 = pro;
//Base& b3 = pri;
}

github

问题3:子类B可以有3种方式(public, protected, private)继承父类A,用哪种方式继承,子类B的子类C的成员函数和子类B的子类C的友元里,才能把子类B的对象转换成父类A的对象呢?

只用当子类B以public或者protected方式继承父类A后,在子类B的子类C的成员函数和子类B的子类C的友元里,才能把子类B的对象转换成父类A的对象。

class Base{
public:
void pub_mem();
protected:
int prot_mem;
private:
char pri_mem;
}; class Pub_derv : public Base{
int f(){
pub_mem();
return prot_mem;
}
//char g(){return pri_mem;}//error
}; class Pro_derv : protected Base{
int f(){
pub_mem();
return prot_mem;
}
//char g(){return pri_mem;}//error
}; class Pri_derv : private Base{
int f(){
pub_mem();
return prot_mem;
}
}; class Pub_Pub_derv : private Pub_derv{
friend void pubpubfri(Pub_Pub_derv&);
int f(){
Base& b = *this;//只用当子类B以public或者protected方式继承父类A后,在子类B的子类C的成员函数和子类B的子类C的友元里,才能把子类B的对象转换成父类A的对象
pub_mem();
return prot_mem;
}
//char g(){return pri_mem;}//error
}; class Pro_Pro_derv : private Pro_derv{
friend void proprofri(Pro_derv&);
int f(){
Base& b = *this;//只用当子类B以public或者protected方式继承父类A后,在子类B的子类C的成员函数和子类B的子类C的友元里,才能把子类B的对象转换成父类A的对象
pub_mem();
return prot_mem;
}
//char g(){return pri_mem;}//error
}; class Pri_Pri_derv : private Pri_derv{
friend void priprifri(Pri_derv&);
int f(){
//Base* b = *this;//error,只用当子类B以public或者protected方式继承父类A后,在子类B的子类C的成员函数和子类B的子类C的友元里,才能把子类B的对象转换成父类A的对象
//pub_mem();
//return prot_mem;
}
}; void pubpubfri(Pub_derv& pd){
Base& b = pd;//只用当子类B以public或者protected方式继承父类A后,在子类B的子类C的成员函数和子类B的子类C的友元里,才能把子类B的对象转换成父类A的对象
}
void proprofri(Pro_derv& pd){
Base& b = pd;//只用当子类B以public或者protected方式继承父类A后,在子类B的子类C的成员函数和子类B的子类C的友元里,才能把子类B的对象转换成父类A的对象
}
void priprifri(Pri_derv& pd){
//Base& b = pd;//error,只用当子类B以public或者protected方式继承父类A后,在子类B的子类C的成员函数和子类B的子类C的友元里,才能把子类B的对象转换成父类A的对象
}
int main(){
Pub_derv pub;
Pro_derv pro;
Pri_derv pri; Base& b1 = pub;
//Base& b2 = pro;
//Base& b3 = pri;
}

github

c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854

c/c++ 继承与多态 由子类向父类的转换规则的更多相关文章

  1. Python开发基础-Day20继承实现原理、子类调用父类的方法、封装

    继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...

  2. python基础之继承实现原理、子类调用父类的方法、封装

    继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...

  3. Java继承,多态,组合应用

    继承:  面向对象的三大特征之一:    是类和类之间的一种拓展关系,是一种从一般到特殊的关系;    格式: sub   extends Super,  我们把sub称为子类或者拓展类, 把supe ...

  4. 初步理解Java的三大特性——封装、继承和多态

    声明:整理自网络,如有雷同,请联系博主处理 一.封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被 ...

  5. Java中的继承和多态

    1.  什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法,使得子类具有父类相同的行为. 特点:在继承关系中,父类更通用.子类更具体.父类具有更 ...

  6. objective-C学习笔记(六)继承与多态

    封装 encapsulation 隐藏对象内部实现细节,对外仅提供公共接口访问. (说白了就是属性啊,方法啊全都写在类内,对外只提供访问,不需要了解细节) 继承 inheritance     一个类 ...

  7. 面向对象的三大特征——封装、继承、多态(&常用关键字)

    一.封装 Encapsulation 在面向对象程式设计方法中,封装是指,一种将抽象性函式接口的实作细节部份包装.隐藏起来的方法. 封装的概念(针对服务器开发,保护内部,确保服务器不出现问题) 将类的 ...

  8. JAVA基础——面向对象三大特性:封装、继承、多态

    JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据. ...

  9. java 学习笔记——类之间的关系之封装、继承与多态的详解

    封装 一个封装的简单例子 封装就是把对象的属性(状态)和方法(行为)结合在一起,并尽可能隐蔽对象的内部细节,成为一个不可分割的独立单位(即对象),对外形成一个边界,只保留有限的对外接口使之与外部发生联 ...

随机推荐

  1. [武汉集训] Cliquers

    题意 设把\(n\)个不同元素分成若干个大小相等的集合的方案个数为\(res\),求\(m^{res}\)模\(10^9-401\)后的余数. (n,m不超过2*10^9) 分析 可以知道,所求答案为 ...

  2. IntelliJ IDEA下SVN的配置及使用说明

    1 下载及安装SVN客户端. 到官网下载小乌龟SVN客户端,官网地址:https://tortoisesvn.net/downloads.html,根据操作系统情况选择适合版本.比如64为操作系统,如 ...

  3. [Abp 源码分析]十、异常处理

    0.简介 Abp 框架本身针对内部抛出异常进行了统一拦截,并且针对不同的异常也会采取不同的处理策略.在 Abp 当中主要提供了以下几种异常类型: 异常类型 描述 AbpException Abp 框架 ...

  4. 1、MySQL主从同步机制及同步中的问题处理

    http://www.drupal001.com/2012/03/mysql-master-slave-troubles/ http://www.jb51.net/article/33052.htm

  5. Android 解压zip文件(支持中文)

    过了n多天后,当再次使用原先博客上写的那篇: Android 压缩解压zip文件 去做zip包的解压的时候,出现了原来没有发现的很多问题.首先是中文汉字问题,使用java的zip包不能很好的解决解压问 ...

  6. ZooKeeper 01 - 什么是ZooKeeper + 部署ZooKeeper集群

    目录 1 什么是ZooKeeper 2 ZooKeeper的功能 2.1 配置管理 2.2 命名服务 2.3 分布式锁 2.4 集群管理 3 部署ZooKeeper集群 3.1 下载并解压安装包 3. ...

  7. Java基础6:代码块与代码加载顺序

    更多内容请关注微信公众号[Java技术江湖] 这是一位阿里 Java 工程师的技术小站,作者黄小斜,专注 Java 相关技术:SSM.SpringBoot.MySQL.分布式.中间件.集群.Linux ...

  8. 网络设备配置与管理(华为)基础系列 :VLAN故障排除和GVRP

    一.VLAN故障排除 故障排除的三步骤:故障定位 → 分析故障 → 排除故障 一般情况下,网络设备配置的故障有两种排错方式 A.静态排错:主要靠display查看配置信息的方式进行 在相关vlan下d ...

  9. [六] 函数式接口的复合方法示例 predicate 谓词逻辑运算 Function接口 组合运算 比较器 逆序 比较链

    复合的方法 有些函数式接口提供了允许复合的方法 也就是可以将Lambda表达式复合成为一个更加复杂的方法 之前的章节中有说到: 接口中的compose, andThen, and, or, negat ...

  10. springboot情操陶冶-web配置(八)

    本文关注应用的安全方面,涉及校验以及授权方面,以springboot自带的security板块作为讲解的内容 实例 建议用户可直接路由至博主的先前博客spring security整合cas方案.本文 ...