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++——派生类中的访问——可见性问题的更多相关文章

  1. C++:调整基类成员在派生类中的访问属性的其他方法(同名成员和访问声明)

    4.3 调整基类成员在派生类中的访问属性的其他方法 4.3.1 同名函数 在定义派生类的时候,C++语言允许在派生类中说明的成员与基类中的成员名字相同,也就是 说,派生类可以重新说明与基类成员同名的成 ...

  2. 3.3 C++改变基类成员在派生类中的访问属性

    参考:http://www.weixueyuan.net/view/6360.html 总结: 使用using声明可以改变基类成员在派生类中的访问属性. private: using book::se ...

  3. 013_linuxC++之_派生类中权限的调整

    (一)在上一篇012_LINUXC++之_类的继承定义中我们知道在派生类中可以访问public和protectd中的数据 (二)那么我们就可以在派生类中将上面两个中的数据进行权限的修改 (三)程序 # ...

  4. cc31a_demo--CppPrimer_静态成员与继承-在派生类中访问基类中的static成员的方法

    //*基类中的static成员,在整个继承层次中只有一个实例 //*在派生类中访问基类中的static成员的方法 //1.基类名::成员名 //2.子类名::成员名 //3.对象.成员名 //4.指针 ...

  5. C++ 派生类成员的访问属性

    派生类成员的访问属性: C++继承方式总共分为以下几种:public.private.protected三种(它们直接影响到派生类的成员.及其对象对基类成员访问的规则).(1)public(公有继承) ...

  6. C++继承 派生类中的内存布局(单继承、多继承、虚拟继承)

    今天在网上看到了一篇写得非常好的文章,是有关c++类继承内存布局的.看了之后获益良多,现在转在我自己的博客里面,作为以后复习之用. ——谈VC++对象模型(美)简.格雷程化    译 译者前言 一个C ...

  7. c++中基类与派生类中隐含的this指针的分析

    先不要看结果,看一下你是否真正了解了this指针? #include<iostream> using namespace std; class Parent{ public: int x; ...

  8. 06 - 从Algorithm 算法派生类中删除ExecuteInformation() 和ExecuteData() VTK 6.0 迁移

    在先前的vtk中,如vtkPointSetAlgorithm 等算法派生类中定义了虚方法:ExecuteInformation() 和 ExecuteData().这些方法的定义是为了平稳的从VTK4 ...

  9. C#在派生类中调用基类成员

    一.在派生类中调用基类成员 在C#的派生类中,我们可以使用base关键字调用基类中的公有或者受保护成员.这些成员只能是构造函数.实例方法或者实例属性. base关键字调用基类成员的语法格式如下: ba ...

随机推荐

  1. redis 带入的挖矿病毒 qW3xT.2 wnTKYg 解决方法

    最近我的阿里云ecs 老是收到 云盾态势感知系统检测到异常 top -c 后发现一个 疑似病毒  /tmp/qW3xT.2 看到网友们的解决方案 试过之后效果不错,可以用的 知道wnTKYg是什么鬼之 ...

  2. Hadoop(19)-MapReduce框架原理-Combiner合并

    1. Combiner概述 2. 自定义Combiner实现步骤 1). 定义一个Combiner继承Reducer,重写reduce方法 public class WordcountCombiner ...

  3. python面向对象-cs游戏示例

    #!/usr/local/bin/python3 # -*- coding:utf-8 -*- class Role(object): n = 123 # 类变量 name = "我是类na ...

  4. hive-show-partitions

    展示分区命令 show partitions show partitions 可以展示这个表格之下的所有分区信息.这个命令常常用在使用SQL语句操作数据之前.举个简单的例子,如果我们想要根据uid融合 ...

  5. centos安装zabbix(server+agent)

    本文包含zabbix_server编译安装,zabbix_agent编译安装,中文字体修正 Mysql模板监控,Nginx模板监控,以及简单的web页面的使用 中文乱码的解决方案 zabbix乱码是字 ...

  6. Redis缓存数据库的安装与配置(3)

    3 Redis主动同步设置方法 Redis主从同步 1.Redis主从同步特点 一个master可以拥有多个slave 多个slave可以连接同一个master,还可以连接到其他slave 主从复制不 ...

  7. Leecode刷题之旅-C语言/python-69x的平方根

    /* * @lc app=leetcode.cn id=69 lang=c * * [69] x 的平方根 * * https://leetcode-cn.com/problems/sqrtx/des ...

  8. 批量安装Python第三方库

    1.首先在python程序的文件夹内,新建一个文本文档,名字自定义,在文档中输入需要安装的第三方库,并用英文半角逗号隔开. import os def getTxt(): txt = open(&qu ...

  9. Python3爬虫(三)请求库的使用之urllib

    Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.urllib库: 1. 是Python内置的HTTP请求库 2. 在Python2中,由urllib和urll ...

  10. oracle 数据被修改怎么修复?(闪回)

    数据被删除 或者 update 的时候忘记勾选where 限制条件,数据全部更新了?  怎么办? 要跑路了? NO !!! 看下面,迅速帮你闪回数据! demo sql: 1. SELECT * FR ...