zoukankan      html  css  js  c++  java
  • 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 继承方式 基类名

  • 相关阅读:
    How to install VXDIAG Honda, Toyota and JLR SDD software
    16% off MPPS V16 ECU tuning tool for EDC15 EDC16 EDC17
    Cummins INSITE locked and ask for verification code
    How to use BMW Multi Tool 7.3 to replace lost key for BMW X1
    Bleed Brake Master Cylinder with Intelligent Tester IT2
    Porsche Piwis Tester II “No VCI has been detected”,how to do?
    Creader VIII VS. Creader VII+
    How to solve GM MDI cannot complete the installation
    汽车OBD2诊断程序开发 (原文转载,思路很清晰!)
    汽车节温器单片机开发思路
  • 原文地址:https://www.cnblogs.com/sun-frederick/p/4772529.html
Copyright © 2011-2022 走看看