c/c++ 继承与多态 由子类向父类的转换规则
问题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
}
问题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;
}
问题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;
}
c/c++ 学习互助QQ群:877684253

本人微信:xiaoshitou5854
c/c++ 继承与多态 由子类向父类的转换规则的更多相关文章
- Python开发基础-Day20继承实现原理、子类调用父类的方法、封装
继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...
- python基础之继承实现原理、子类调用父类的方法、封装
继承实现原理 python中的类可以同时继承多个父类,继承的顺序有两种:深度优先和广度优先. 一般来讲,经典类在多继承的情况下会按照深度优先的方式查找,新式类会按照广度优先的方式查找 示例解析: 没有 ...
- Java继承,多态,组合应用
继承: 面向对象的三大特征之一: 是类和类之间的一种拓展关系,是一种从一般到特殊的关系; 格式: sub extends Super, 我们把sub称为子类或者拓展类, 把supe ...
- 初步理解Java的三大特性——封装、继承和多态
声明:整理自网络,如有雷同,请联系博主处理 一.封装 封装从字面上来理解就是包装的意思,专业点就是信息隐藏,是指利用抽象数据类型将数据和基于数据的操作封装在一起,使其构成一个不可分割的独立实体,数据被 ...
- Java中的继承和多态
1. 什么是继承,继承的特点? 子类继承父类的特征和行为,使得子类具有父类的各种属性和方法.或子类从父类继承方法,使得子类具有父类相同的行为. 特点:在继承关系中,父类更通用.子类更具体.父类具有更 ...
- objective-C学习笔记(六)继承与多态
封装 encapsulation 隐藏对象内部实现细节,对外仅提供公共接口访问. (说白了就是属性啊,方法啊全都写在类内,对外只提供访问,不需要了解细节) 继承 inheritance 一个类 ...
- 面向对象的三大特征——封装、继承、多态(&常用关键字)
一.封装 Encapsulation 在面向对象程式设计方法中,封装是指,一种将抽象性函式接口的实作细节部份包装.隐藏起来的方法. 封装的概念(针对服务器开发,保护内部,确保服务器不出现问题) 将类的 ...
- JAVA基础——面向对象三大特性:封装、继承、多态
JAVA面向对象三大特性详解 一.封装 1.概念: 将类的某些信息隐藏在类内部,不允许外部程序直接访问,而是通过该类提供的方法来实现对隐藏信息的操作和访问. 2.好处: 只能通过规定的方法访问数据. ...
- java 学习笔记——类之间的关系之封装、继承与多态的详解
封装 一个封装的简单例子 封装就是把对象的属性(状态)和方法(行为)结合在一起,并尽可能隐蔽对象的内部细节,成为一个不可分割的独立单位(即对象),对外形成一个边界,只保留有限的对外接口使之与外部发生联 ...
随机推荐
- 武汉软件开发:一看就会的wpf入门教程
据了解,目前武汉软件开发市场关于PC端桌面开发的技术主要有两块:winform和wpf.wpf是微软既winform之后推出的一套新的桌面开发技术.采用数据驱动的方式可以轻松编写出非常炫的界面. 1. ...
- Linux查找文件内容
从当前目录递归查找文件名为 .py 中包含 conf 的文件名: find -name "*.py" | xargs grep "conf"
- BBS论坛(十)
10.1.客户端权限验证功能完成 (1)cms/cms_profile 显示当前用户的角色和权限 <tr> <td>角色:</td> <td> {% f ...
- 什么?你竟然还没有用这几个chrome插件?
前言 其实18年之前写过一篇关于chrome插件的文章,里面安利了4个chrome插件.鉴于这已经是9102年了,之前觉得好用的chrome插件跟新了解到的比起来,还是差了那么点味道.所以决定再更新一 ...
- JDBC 连接池的两种方式——dbcp & c3p0
申明:本文对于连接资源关闭采用自定义的 JDBCUtils 工具: package com.test.utils; import java.sql.Connection; import java.sq ...
- ES6躬行记(13)——类型化数组
类型化数组(Typed Array)是一种处理二进制数据的特殊数组,它可像C语言那样直接操纵字节,不过得先用ArrayBuffer对象创建数组缓冲区(Array Buffer),再映射到指定格式的视图 ...
- 在数据采集器中用TensorFlow进行实时机器学习
最新DataOps平台的真正价值,只有在业务用户和应用程序能够从各种数据源来访问原始数据和聚合数据,并且及时地产生数据驱动的认识时,才能够实现.利用机器学习(Machine Learning),分析师 ...
- 痞子衡嵌入式:ARM Cortex-M文件那些事(7)- 反汇编文件(.s/.lst/.dump)
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家讲的是嵌入式开发里的反汇编文件(.s, .lst, .dump). 痞子衡在第四.五.六节课分别介绍了编译器/链接器生成的3种output文件( ...
- 浅谈cookie和session
Cookie简介 Cookie(复数形态Cookies),中文名称为“小型文本文件”,指某些网站为了辨别用户身份或存储用户相关信息而存储在用户本地终端(Client Side) 上的数据(通常为加密数 ...
- Chrome F12调试工具常用技巧
原文地址:http://www.cnblogs.com/MuYunyun/p/5678405.html#3471461 阅读目录 Chrome调试工具介绍: 快速切换文件 在源代码中搜索 在源代码中快 ...