C++——派生类中的访问——可见性问题
C++中派生类对基类成员的访问形式主要有以下两种:
1、内部访问:由派生类中新增成员对基类继承来的成员的访问。
2、对象访问:在派生类外部,通过派生类的对象对从基类继承来的成员的访问。今天给大家介绍在3中继承方式下,派生类对基类成员的访问规则。
1、私有继承的访问规则
当类的继承方式为私有继承时,基类的public成员和protected成员被继承后成为派生类的private成员,派生类的其它成员可以直接访问它们,但是在类的外部通过派生类的对象无法访问。基类的private成员在私有派生类中是不可直接访问的,所以无论是派生类的成员还是通过派生类的对象,都无法直接访问从基类继承来的private成员,但是可以通过基类提供的public成员函数间接访问。私有继承的访问规则总结如下:
基类成员 private成员 public成员 protected成员
内部访问 不可访问 可访问 可访问
对象访问 不可访问 不可访问 不可访问
2、公有继承的访问规则
当类的继承方式为公有继承时,基类的public成员和protected成员被继承到派生类中仍作为派生类的public成员和protected成员,派生类的其它成员可以直接访问它们。但是,类的外部使用者只能通过派生类的对象访问继承来的public成员。基类的private成员在私有派生类中是不可直接访问的,所以无论是派生类成员还是派生类的对象,都无法直接访问从基类继承来的private成员,但是可以通过基类提供的public成员函数直接访问它们。公有继承的访问规则总结如下:
基类成员 private成员 public成员 protected成员
内部访问 不可访问 可访问 可访问
对象访问 不可访问 可访问 不可访问
3、保护继承的访问规则
当类的继承方式为保护继承时,基类的public成员和protected成员被继承到派生类中都作为派生类的protected成员,派生类的其它成员可以直接访问它们,但是类的外部使用者不能通过派生类的对象访问它们。基类的private成员在私有派生类中是不可直接访问的,所以无论是派生类成员还是通过派生类的对象,都无法直接访问基类中的private成员。保护继承的访问规则总结如下:
基类成员 private成员 public成员 protected成员
内部访问 不可访问 可访问 可访问
对象访问 不可访问 不可访问 不可访问
派生类中的访问——可见性问题
1、 对于在不同作用域声明的标识符,可见性原则:
若存在两个或多个具有包含关系的作用域,外层声明了一个标识符,而内层没有再次声明同名标识符,则外层标识符在内层仍然可见;
若在内层声明了同名标识符,则外层标识符在内层不可见,这时内层变量隐藏了外层的同名变量,这种现象称为隐藏规则。
其中,外层为基类,内层为派生类。
2、 作用域:
使用::作用域限定要访问的成员所在类的名称。
基类和派生类新增的成员都具有类作用域,但作用范围不同:是相互保护的两个层,派生类在内层。
(1)单继承中的同名隐藏
在没有使用虚函数的情况下,若派生类声明了一个和基类成员同名的新成员函数,即使函数的参数表不同,那么从基类继承的同名函数的所有重载形式也都被隐藏(外层基类中的同名成员函数被隐藏),使用成员名只能访问到派生类的成员函数。若要访问被隐藏的基类成员,必须使用基类名和作用域符::限定,使用基类名::成员名访问。
隐藏规则在私有继承中的应用
在私有继承时,为保证基类的公有成员能在派生类中访问,必须在派生类中重新声明同名的成员。在调用时,根据同名隐藏的规则,使用派生类中的函数。若对基类继承过来的某些函数功能进行扩充和改造,可以通过隐藏实现。
(2)多继承中的同名隐藏及访问冲突问题
①各基类没有任何继承关系,同时没有共同基类的情况:
在没有使用虚函数的情况下,若派生类的多个基类拥有同名的成员,同时派生类又新增了同名的成员函数时,派生类将隐藏所有基类的同名函数。
隐藏访问及隐藏冲突:
A 使用“对象名.成员名”可唯一标识和访问新增派生类成员;——隐藏
B 只有使用“对象名.基类名::成员名”这种作用域标识符可以访问基类的同名成员;
C若派生类没有声明同名函数,使用“对象名.成员名”无法唯一标示成员——冲突!
只能通过“对象名.基类名::成员名”访问基类的成员。
② 有间接基类的情况
A
B1 B2
C
对于派生类C,其直接基类B1、B2,间接基类A。
若B1 B2分别定义了同名的成员,而派生类C没有新增该同名函数,则使用“类C的对象名.成员名”产生冲突!只能使用“类C的对象名.B1/B2::成员名”可以访问B1/B2中的同名成员;但任何方式都无法访问A中的同名成员。(同①)
若要访问类A中的成员,而在B1 B 2 C中没有新增同名的成员,通过“类C的对象名.A中成员名”或“类C的对象名.A::A中成员名”访问类A中的成员,产生冲突!只有通过
“类C的对象名.B1/B2::成员名”访问类A中的成员。
若派生类C声明了同名函数,则使用“类C的对象名.成员名”访问的是C类新增的同名成员函数——隐藏
小结:
同名成员的唯一标识问题:
•使用作用域符::唯一标识派生类中由直接基类继承的成员;
派生类对象.直接基类名::同名成员/同名成员函数
•将共同基类设置为虚基类,这时从不同的路径继承过来的同名成员在内存中只要一个拷贝,同一个函数也只有一个路径。声明虚基类是在派生类定义过程中进行的:
class 派生类名:virtual 继承方式 基类名
C++——派生类中的访问——可见性问题的更多相关文章
- C++:调整基类成员在派生类中的访问属性的其他方法(同名成员和访问声明)
4.3 调整基类成员在派生类中的访问属性的其他方法 4.3.1 同名函数 在定义派生类的时候,C++语言允许在派生类中说明的成员与基类中的成员名字相同,也就是 说,派生类可以重新说明与基类成员同名的成 ...
- 3.3 C++改变基类成员在派生类中的访问属性
参考:http://www.weixueyuan.net/view/6360.html 总结: 使用using声明可以改变基类成员在派生类中的访问属性. private: using book::se ...
- 013_linuxC++之_派生类中权限的调整
(一)在上一篇012_LINUXC++之_类的继承定义中我们知道在派生类中可以访问public和protectd中的数据 (二)那么我们就可以在派生类中将上面两个中的数据进行权限的修改 (三)程序 # ...
- cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法
//*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...
- C++ 派生类成员的访问属性
派生类成员的访问属性: C++继承方式总共分为以下几种:public.private.protected三种(它们直接影响到派生类的成员.及其对象对基类成员访问的规则).(1)public(公有继承) ...
- C++继承 派生类中的内存布局(单继承、多继承、虚拟继承)
今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化 译 译者前言 一个C ...
- c++中基类与派生类中隐含的this指针的分析
先不要看结果,看一下你是否真正了解了this指针? #include<iostream> using namespace std; class Parent{ public: int x; ...
- 06 - 从Algorithm 算法派生类中删除ExecuteInformation() 和ExecuteData() VTK 6.0 迁移
在先前的vtk中,如vtkPointSetAlgorithm 等算法派生类中定义了虚方法:ExecuteInformation() 和 ExecuteData().这些方法的定义是为了平稳的从VTK4 ...
- C#在派生类中调用基类成员
一.在派生类中调用基类成员 在C#的派生类中,我们可以使用base关键字调用基类中的公有或者受保护成员.这些成员只能是构造函数.实例方法或者实例属性. base关键字调用基类成员的语法格式如下: ba ...
随机推荐
- git上下载的thinkphp框架报错解决方法
git上下载的thinkphp5框架使用.gitignore没上传依赖,需要通过composer进行下载依赖,使用composer install或者composer update即可解决.
- Hue联合(hdfs yarn hive) 后续......................
1.启动hdfs,yarn start-all.sh 2.启动hive $ bin/hive $ bin/hive --service metastore & $ bin/hive --ser ...
- Python的scrapy学习心得
scrapy框架是Python爬虫的一个使用起来不错的框架,通过这个框架可以很快的爬出自己想要的数据 官方的定义是如下的图片,其实看不太懂 在平常使用这个框架的时候,主要用三部分,spider爬虫主体 ...
- Scrapy框架的初步使用
Scrapy scrapy框架是一个非常全面的爬虫框架,可以说是爬虫界的django了,里面有相当多的组件,格式化组件item,持久化组件pipeline,爬虫组件spider 首先我们要先和djan ...
- 《Go语言实战》书摘
书籍简介 名称:Go语言实战 作者: 威廉·肯尼迪 (William Kennedy) / 布赖恩·克特森 (Brian Ketelsen) / 埃里克·圣马丁 (Erik St.Martin) 内容 ...
- pxe无人值守安装linux机器笔记----摘抄
1. 基建工作 1.关闭防火墙 a)service iptables stop b)service ip6tables stop c)chkconfig iptables off d)chkconfi ...
- 在spring+beranate中多数据源中使用 ThreadLocal ,总结的原理 --费元星
设计模式 首先,ThreadLocal 不是用来解决共享对象的多线程访问问题的,一般情况下,通过ThreadLocal.set() 到线程中的对象是该线程自己使用的对象,其他线程是不需要访问的,也访问 ...
- Android Google Maps 开始
由于工作需要,最近对Android的各大地图进行了试用. 其中有Google地图,百度地图,高德地图,还有开源的OSM. 在使用Google地图的时候,官网流程写的非常清楚,但是其中也遇到一些问题.这 ...
- NLP系列-中文分词(基于词典)
中文分词概述 词是最小的能够独立活动的有意义的语言成分,一般分词是自然语言处理的第一项核心技术.英文中每个句子都将词用空格或标点符号分隔开来,而在中文中很难对词的边界进行界定,难以将词划分出来.在汉语 ...
- ardupilot_gazebo仿真(二)
ardupilot_gazebo仿真(二) 标签(空格分隔): 未分类 在模型中添加sensor gezebo官网-sensor部分教程 gezebo官网-基础部分教程 Gazebo plugins ...