Public Private Protect Inheritance and access specifiers

2023-11-20

In the previous lessons on inheritance, we’ve been making all of our data members public in order to simplify the examples. In this section, we’ll talk about the role of access specifiers in the inheritance process, as well as cover the different types of inheritance possible in C++.

To this point, you’ve seen the private and public access specifiers, which determine who can access the members of a class. As a quick refresher, public members can be accessed by anybody. Private members can only be accessed by member functions of the same class. Note that this means derived classes can not access private members!

1
2
3
4
5
6
7
class Base
{
private :
     int m_nPrivate; // can only be accessed by Base member functions (not derived classes)
public :
     int m_nPublic; // can be accessed by anybody
};

When dealing with inherited classes, things get a bit more complex.

First, there is a third access specifier that we have yet to talk about because it’s only useful in an inheritance context. The protected access specifier restricts access to member functions of the same class, or those of derived classes.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Base
{
public :
     int m_nPublic; // can be accessed by anybody
private :
     int m_nPrivate; // can only be accessed by Base member functions (but not derived classes)
protected :
     int m_nProtected; // can be accessed by Base member functions, or derived classes.
};
 
class Derived: public Base
{
public :
     Derived()
     {
         // Derived's access to Base members is not influenced by the type of inheritance used,
         // so the following is always true:
 
         m_nPublic = 1; // allowed: can access public base members from derived class
         m_nPrivate = 2; // not allowed: can not access private base members from derived class
         m_nProtected = 3; // allowed: can access protected base members from derived class
     }
};
 
int main()
{
     Base cBase;
     cBase.m_nPublic = 1; // allowed: can access public members from outside class
     cBase.m_nPrivate = 2; // not allowed: can not access private members from outside class
     cBase.m_nProtected = 3; // not allowed: can not access protected members from outside class
}

Second, when a derived class inherits from a base class, the access specifiers may change depending on the method of inheritance. There are three different ways for classes to inherit from other classes: public, private, and protected.

To do so, simply specify which type of access you want when choosing the class to inherit from:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// Inherit from Base publicly
class Pub: public Base
{
};
 
// Inherit from Base privately
class Pri: private Base
{
};
 
// Inherit from Base protectedly
class Pro: protected Base
{
};
 
class Def: Base // Defaults to private inheritance
{
};

If you do not choose an inheritance type, C++ defaults to private inheritance (just like members default to private access if you do not specify otherwise).

That gives us 9 combinations: 3 member access specifiers (public, private, and protected), and 3 inheritance types (public, private, and protected).

The rest of this section will be devoted to explaining the difference between these.

Before we get started, the following should be kept in mind as we step through the examples. There are three ways that members can be accessed:

  • A class can always access it’s own members regardless of access specifier.
  • The public accesses the members of a class based on the access specifiers of that class.
  • A derived class accesses inherited members based on the access specifiers of its immediate parent. A derived class can always access it’s own members regardless of access specifier.

This may be a little confusing at first, but hopefully will become clearer as we step through the examples.

Public inheritance

Public inheritance is by far the most commonly used type of inheritance. In fact, very rarely will you use the other types of inheritance, so your primary focus should be on understanding this section. Fortunately, public inheritance is also the easiest to understand. When you inherit a base class publicly, all members keep their original access specifications. Private members stay private, protected members stay protected, and public members stay public.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
class Base
{
public :
     int m_nPublic;
private :
     int m_nPrivate;
protected :
     int m_nProtected;
};
 
class Pub: public Base
{
     // Public inheritance means:
     // m_nPublic stays public
     // m_nPrivate stays private
     // m_nProtected stays protected
 
     Pub()
     {
         // The derived class always uses the immediate parent's class access specifications
         // Thus, Pub uses Base's access specifiers
         m_nPublic = 1; // okay: anybody can access public members
         m_nPrivate = 2; // not okay: derived classes can't access private members in the base class!
         m_nProtected = 3; // okay: derived classes can access protected members
     }
};
 
int main()
{
     // Outside access uses the access specifiers of the class being accessed.
     // In this case, the access specifiers of cPub.  Because Pub has inherited publicly from Base,
     // no access specifiers have been changed.
     Pub cPub;
     cPub.m_nPublic = 1; // okay: anybody can access public members
     cPub.m_nPrivate = 2; // not okay: can not access private members from outside class
     cPub.m_nProtected = 3; // not okay: can not access protected members from outside class
}

This is fairly straightforward. The things worth noting are:

  1. Derived classes can not directly access private members of the base class.
  2. The protected access specifier allows derived classes to directly access members of the base class while not exposing those members to the public.
  3. The derived class uses access specifiers from the base class.
  4. The outside uses access specifiers from the derived class.

To summarize in table form:

Public inheritance
Base access specifier Derived access specifier Derived class access? Public access?
Public Public Yes Yes
Private Private No No
Protected Protected Yes No

Private inheritance

With private inheritance, all members from the base class are inherited as private. This means private members stay private, and protected and public members become private.

Note that this does not affect that way that the derived class accesses members inherited from its parent! It only affects the code trying to access those members through the derived class.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
class Base
{
public :
     int m_nPublic;
private :
     int m_nPrivate;
protected :
     int m_nProtected;
};
 
class Pri: private Base
{
     // Private inheritance means:
     // m_nPublic becomes private
     // m_nPrivate stays private
     // m_nProtected becomes private
 
     Pri()
     {
         // The derived class always uses the immediate parent's class access specifications
         // Thus, Pub uses Base's access specifiers
         m_nPublic = 1; // okay: anybody can access public members
         m_nPrivate = 2; // not okay: derived classes can't access private members in the base class!
         m_nProtected = 3; // okay: derived classes can access protected members
     }
};
 
int main()
{
     // Outside access uses the access specifiers of the class being accessed.
     // Note that because Pri has inherited privately from Base,
     // all members of Base have become private when access through Pri.
     Pri cPri;
     cPri.m_nPublic = 1; // not okay: m_nPublic is now a private member when accessed through Pri
     cPri.m_nPrivate = 2; // not okay: can not access private members from outside class
     cPri.m_nProtected = 3; // not okay: m_nProtected is now a private member when accessed through Pri
 
     // However, we can still access Base members as normal through Base:
     Base cBase;
     cBase.m_nPublic = 1; // okay, m_nPublic is public
     cBase.m_nPrivate = 2; // not okay, m_nPrivate is private
     cBase.m_nProtected = 3; // not okay, m_nProtected is protected
}

To summarize in table form:

Private inheritance
Base access specifier Derived access specifier Derived class access? Public access?
Public Private Yes No
Private Private No No
Protected Private Yes No

Protected inheritance

Protected inheritance is the last method of inheritance. It is almost never used, except in very particular cases. With protected inheritance, the public and protected members become protected, and private members stay private.

To summarize in table form:

Protected inheritance
Base access specifier Derived access specifier Derived class access? Public access?
Public Protected Yes No
Private Private No No
Protected Protected Yes No

Protected inheritance is similar to private inheritance. However, classes derived from the derived class still have access to the public and protected members directly. The public (stuff outside the class) does not.

Summary

The way that the access specifiers, inheritance types, and derived classes interact causes a lot of confusion. To try and clarify things as much as possible:

First, the base class sets it’s access specifiers. The base class can always access it’s own members. The access specifiers only affect whether outsiders and derived classes can access those members.

Second, derived classes have access to base class members based on the access specifiers of the immediate parent. The way a derived class accesses inherited members is not affected by the inheritance method used!

Finally, derived classes can change the access type of inherited members based on the inheritance method used. This does not affect the derived classes own members, which have their own access specifiers. It only affects whether outsiders and classes derived from the derived class can access those inherited members.

A final example:

1
2
3
4
5
6
7
8
9
class Base
{
public :
     int m_nPublic;
private :
     int m_nPrivate;
protected :
     int m_nProtected;
};

Base can access it’s own members without restriction. The public can only access m_nPublic. Derived classes can access m_nPublic and m_nProtected.

1
2
3
4
5
6
7
8
9
class D2: private Base
{
public :
     int m_nPublic2;
private :
     int m_nPrivate2;
protected :
     int m_nProtected2;
}

D2 can access it’s own members without restriction. D2 can access Base’s members based on Base’s access specifiers. Thus, it can access m_nPublic and m_nProtected, but not m_nPrivate. Because D2 inherited Base privately, m_nPublic, m_nPrivate, and m_nProtected are now private when accessed through D2. This means the public can not access any of these variables when using a D2 object, nor can any classes derived from D2.

1
2
3
4
5
6
7
8
9
class D3: public D2
{
public :
     int m_nPublic3;
private :
     int m_nPrivate3;
protected :
     int m_nProtected3;
};

D3 can access it’s own members without restriction. D3 can access D2′s members based on D2′s access specifiers. Thus, D3 has access to m_nPublic2 and m_nProtected2, but not m_nPrivate2. D3 access to Base members is controlled by the access specifier of it’s immediate parent. This means D3 does not have access to any of Base’s members because they all became private when D2 inherited them.

http://www.learncpp.com/cpp-tutorial/115-inheritance-and-access-specifiers/

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Public Private Protect Inheritance and access specifiers 的相关文章

  • Linux系统上Hadoop的配置

    目录 1 免密登录 2 设置java安装的根目录 3 hadoop参数配置 hadoop地址配置 1 免密登录 cd ssh ls ssh keygen t rsa P f ssh id rsa ls 多了两个文件 id rsa id rs

随机推荐

  • 杭电ACM 1004题

    原题大概意思就是统计输入字符串中 重复的最大个数 import java util Scanner public class Main public static void main String args Scanner sc new S
  • C++ Primer 第五版 电子书(英文)pdf下载

    C Primer 第五版 电子书 英文 pdf下载下载链接 https pan baidu com s 13BQ93O0g8QaNq4ultcxhKA 提取码获取方式 关注下面微信公众号 回复关键字 1169
  • Tensorflow 机器翻译NMT笔记 1 快速上手

    开始 首先 这篇博客基本基于 https github com tensorflow nmt 的内容来的 作为个人学习的笔记 也当做一个博客内容分享 顺序和Github上的顺序有一些区别 注意咯 首先 这里讲的是一个基于Seq2Seq实现的
  • Python 正则表达式指南

    文章目录 1 正则表达式基础 1 1 简单介绍 1 2 数量词的贪婪模式与非贪婪模式 1 3 反斜杠的困扰 1 4 匹配模式 2 re模块 2 1 开始使用re 2 2 Match 2 3 Pattern 1 正则表达式基础 1 1 简单介
  • Vue2基础框架(js)

    快捷方式 vba div div
  • IO相关-这一篇全了解

    什么是比特 什么是字节 什么是字符 它们长度是多少 各有什么区别 解 Bit最小的二进制单位 是计算机的操作部分 取值0或者1 Byte是计算机操作数据的最小单位由8位bit组成 取值 128 127 Char是用户的可读写的最小单位 在J
  • 由一个多线程共享Integer类变量问题引起的。。。

    假设并发环境下 业务代码中存在一些统计操作 为了保证线程安全 开发人员往往会对计数值进行加锁 synchronized 值得注意的是 直接对Integer类型进行加锁 似乎并不会达到预期效果 比如下面这段代码 Integer num new
  • java 视频压缩

    原文链接 https blog csdn net SeniorShen article details 113246990 1 引入依赖
  • C++拷贝构造函数的使用:创建类Dog 成员变量name age 。完成该类的定义,该类包含构造函数,拷贝构造函数 析构函数

    创建类Dog 成员变量name age 大家完成该类的定义 该类包含构造函数 拷贝构造函数 析构函数 拷贝构造函数的作用 拷贝构造函数作用就是利用该类的一个对象是初始化另一个该类的对象 换句话说就是 拷贝构造函数的作用 通过一个对象对该类的
  • 使用ADB命令来测试Android手机App的耗电量

    1 使用WiFi连接手机 先使用USB数据线连接手机和电脑 手机和电脑连接同一个WiFi 启动端口服务 adb tcpip 5555 5555为端口号 可以自由指定 打印 restarting in TCP mode port 5555 表
  • 如何用Stata完成(shui)一篇经济学论文(十一):分组和去重

    文章目录 分组 去重 不出意外的话 这应该是stata有关数据处理的最后一篇 emmm 其实我一开始只打算写数据处理部分的stata教程 因为我觉得对于我来说 数据处理才是最头疼的部分 不过关于后面回归 还是有些东西想跟大家分享一下 开始挖
  • Halcon直线检测

    1 Halcon最常用的直线检测算子 add metrology object line measure 利用Halcon封装好的模型不仅可以检测直线 还可以检测圆 椭圆 矩形等 下面介绍下其余的直线检测的算子 需要配合 skeleton
  • CentOS7安装postgresql

    目录 1 安装postgresql 2 postgresql基本使用 常用启停命令 常用配置文件 常用postgresql命令 官网地址 https www postgresql org 1 安装postgresql 1 1 进入官网 点击
  • 两点。。。等来金蝶中间件的面试通知

    晚上笔试 说是大约一点通知 等到十二点 困了 上床 睡不着啊 1点半翻起来 打开手机 没有 打开Gmail 没有 于是抽了支烟 等到两点多一点 手机响了 接到面试通知 下午一点 石头终于落地 因为上午还有一场网易游戏的笔试 担心冲突 还好
  • Linux编辑器——vim的使用

    文章目录 1 vim的三种模式 2 vim的基本操作 3 vim的配置 前言 Linux上的编辑器有很多 比如nano vi vim等 nano是最简单的编辑器 vim编辑器常用于写代码 因为vim的功能强大 写代码快捷方便 其可以主动的用
  • 16.1 C++智能指针-new/delete探秘

    16 1 C 智能指针 new delete探秘 16 2 C 智能指针 shared ptr 16 3 C 智能指针 weak ptr 16 4 C 智能指针 shared ptr使用场景 陷阱 性能分析与使用建议 16 5 C 智能指针
  • Queue队列简介说明

    转自 Queue队列简介说明 下文笔者讲述Queue队列的简介说明 如下所示 Queue队列简介 Queue也是Java集合框架中定义的一种接口 直接继承自 Collection 接口 除了基本的Collection接口规定测操作外 Que
  • 制作一个多语言谷歌翻译 脚本

    1 修改host文件 C Windows System32 drivers etc 加入以下配置 google translate 203 208 40 66 translate google com google translate ap
  • 成功的硬件公司不仅是产品,更是一种创新文化

    目录 内容简介 客户 建立公司 而不仅仅是产品 CSDN学院 作者简介 内容简介 很多时候 你决定去做一件事 一款产品 往往都始于一个想法 一个灵感 然后 许多硬件创业者会花费数月 甚至是数年的时间来确定并分析他们的想法或者说是创意 一旦产
  • Public Private Protect Inheritance and access specifiers

    In the previous lessons on inheritance we ve been making all of our data members public in order to simplify the example