C++中的private, public, protected

2023-05-16

0.概述

数据隐藏是C++面向对象编程的重要特征之一,它允许我们隐藏对象内部细节即数据成员,防止程序的函数直接访问一个类对象的内部表示、数据成员和成员函数。

对类成员函数的访问限制由访问修饰符指定。访问修饰符在 C++ 中也称为可见性模式,private、public 和 protected 都是可见性模式的类型。我们将在本文接下来的部分中详细讨论它们中的每一个。

可见性模式让我们知道基类将如何被派生类继承,以及基类的哪些成员将被派生类获取和访问。给出名称可见性模式或访问说明符,因为它们用于定义类成员的可访问性和可见性级别。

当派生类的对象可以使用基类中的成员函数时,访问说明符主要用于继承。从基类派生子类时使用访问说明符的一般语法是:

class Base {
// content of the base class 
};

class Derived: access_specifier Base {
// content of the child's class
};

在上面的代码中,我们有一个基类Base和一个派生类Derived,以及access_specifier告诉我们基类的哪些成员将被派生类获取和访问。

C++ 中的一个类可以有多个public、protected或private部分。我们可以在下面的代码中看到我们如何在类中使用可见性模式:

class base {
public:
   // public members go here
protected:
   // protected members go here
private:
   // private members go here
};

在上面的代码中,我们有一个基类base,有多个部分被访问说明符分开。

注意:如果未指定可见性模式,则默认情况下会考虑private模式。

1.private成员

在private可见性模式下,当我们从父类继承子类时,那么基类的所有成员(public、private和protected成员)在派生类中都会变成private。

这些成员在派生类之外的访问是有限制的,只能被派生类的成员函数或友元函数访问。

下面的框图可以说明当派生类的访问方式为private时,基类的数据成员是如何被继承的。

从上图中可以看出,private变量a在派生类中是不可访问的,因为它在基类内部是private类型,所以只能被基类内部的成员函数访问。基类的public变量c和protected变量b在派生类中会变成private,只能被派生类的成员函数访问。

借助一个非常基本的现实生活示例,我们可以了解何时需要哪个访问说明符,假设在任何社交媒体应用程序上,你想更新状态,但你对谁可以看到这个有一些要求和限制互联网上的地位。所以,如果你希望没有人看到这个状态或者它应该“只对我可见”,那么这意味着你正在遵循“private访问说明符”的概念。

1.1例子

让我们看一个例子来理解private可见性模式的概念及其提供的限制:

class Parent
{
    private:
     int x1;
    protected:
     int x2;
    public:
     int x3;
};
class Child: private Parent
{

};

在上面的代码中,由于可见模式是private,所以,基类的所有成员在派生类中都变成了private。当派生类的对象试图访问派生类之外的这些成员时,将抛出该错误。

现在,让我们再用一个 C++ 程序来演示当基类的对象试图访问类外的private数据成员x时private访问说明符的作用。

class base
{  
    // private data member
    private:
        int x;
    // public member function   
    public:   
        void  fun()
        {   
            // member function of the base class can access private data member
            return 2 * x;
        }
     
};
 
// main function
int main()
{  
    // creating object of the class
    base obj;
     
    // trying to access private data members directly outside the class
    obj.x = 78;
    cout << obj.fun() << endl;
}

上述程序的输出将是编译时错误,因为我们不允许直接从类外部访问类成员的private数据。

但是,我们可以通过调用基类的public成员函数来间接访问基类的private数据成员。

1.2辅助功能

private模式的可访问性可以总结如下:

Accessibility

Private mode

Same class

Yes

Derived class

No

Other class

No

Anywhere in the program

No

在 private 访问说明符下定义的成员只能在同一个类中访问,它们在派生类或程序的任何其他类中是不可访问的。

2.public成员

在public可见性模式下,当我们从父类继承子类时,基类的public成员、private成员和protected成员在派生类中也分别保持public成员、private成员和protected成员。public可见性模式保留了父类所有成员的可访问性。

父类的public成员可由子类和所有其他类访问。基类的protected成员只能在派生类及其继承类中访问。但是,子类无法访问private成员。

下面的框图可以说明派生类访问方式为public时,基类的数据成员是如何被继承的。

从上图可以看出,private变量a在派生类中是不可访问的,因为它是private类型,所以只能被基类的成员函数访问。public变量a将保持public状态,子类和所有其他类都可以访问。基类的protected变量b将在派生类中保持protected状态,并且只能在派生类及其继承类中访问。

回到现实生活中更新任何社交媒体应用程序状态的例子,我们在上面已经提到,假设你希望互联网上的任何人都可以看到你的状态,那么,这意味着你遵循“公开”的概念访问说明符”。

2.1例子

让我们看一个例子来理解public可见性模式的概念及其提供的限制:

class Parent
{
    private:
     int x1;
    protected:
     int x2;
    public:
     int x3;
};
class Child: public Parent
{

};

上述代码中,保护变量x2将从Parent类继承,并在Child类及其继承类中访问,同理,public变量x3将从Parent类继承,并在Child和其它类中可以访问,但private变量 x1 将无法在 Child 类中访问。

现在,让我们再用一个 C++ 程序来演示当基类的对象试图在 main() 函数中访问类外部的public数据成员x时public访问说明符的工作。

class base
{
    public:
        int x;
        void  fun()
        {
            return 2 * x;
        }
     
};
 
// main function
int main()
{
    // creating object of the derived class
    base obj;
     
    // accessing public data members outside class
    obj.x = 9;
     
    cout << obj.x << endl;
    cout << obj.fun();
}

上述程序的输出将是:

9
18

在上面的程序中,数据成员x被声明为public,因此它可以在任何类中访问,也可以从类外访问。

2.2辅助功能

public模式的可访问性可以总结如下:

Accessibility

Public mode

Same class

Yes

Derived class

Yes

Other class

Yes

Anywhere in the program

Yes

在 public 访问说明符下定义的成员在任何地方都可以访问,在同一个类中,在派生类中,在任何其他类中,甚至在类之外。

3.protected成员

在protected可见性模式下,当我们从父类继承子类时,那么基类的所有成员都会成为派生类的protected成员。

因此,这些成员现在只能由派生类及其成员函数访问。这些成员也可以被继承,并将可供该派生类的继承子类访问。

下面的框图可以说明在保护派生类访问方式的情况下,基类的数据成员是如何被继承的。

从上图可以看出,private变量a在派生类中是不可访问的,因为它是private类型,所以只能被基类的成员函数访问。public变量a将在派生类中受到保护,并且只能由该派生类的继承子类访问。基类的protected变量b将在派生类中保持protected状态,并且只能在派生类及其继承类中访问。

再一次,回到现实生活中更新任何社交媒体应用程序状态的例子,我们在上面假设,现在,如果你希望你的状态只对你的朋友和你朋友的朋友可见,那么,意味着你遵循“protected访问说明符”的概念。

3.1例子

让我们看一个例子来理解protected可见性模式的概念及其提供的限制:

class Parent
{
    private:
     int x1;
    protected:
     int x2;
    public:
     int x3;
};
class Child: protected Parent
{

};

在上面的代码中,由于可见性模式被保护,Parent类的protected和public成员将成为Child类的protected成员。

protected变量x2将从Parent类继承,在Child类中可以访问,同理,public变量x3作为protected成员从父类继承,在Child类中可以访问,但是private变量x1 在 Child 类中将不可访问。

现在,让我们再用一个 C++ 程序来演示当基类的对象试图在 main() 函数中访问类外部的protected数据成员x时protected访问说明符的工作原理。

class base
{
    protected:
        int x;
        void  fun()
        {
            return 2 * x;
        }
     
};
 
// main function
int main()
{
    // creating object of the derived class
    base obj;
     
    // accessing public data members outside class
    obj.x = 9;
     
    cout << obj.x << endl;
    cout << obj.fun();
}

上述程序的输出将是:

9
18

在上面的程序中,数据成员x被声明为protected,因此它可以被基类的任何子类(派生类)访问。

3.2辅助功能

保护模式的可访问性可以总结如下:

Accessibility

Protected mode

Same class

Yes

Derived class

Yes

Inherited subclasses of the derived class

Yes

Other class

No

Anywhere in the program

No

在protected访问说明符下定义的成员可在派生类及其继承类中访问。

4.对比与总结

C++ 中 Private、Public 和 Protected 的区别

Private

Public

Protected

声明为private类成员只能由基类内部的函数访问。

可以从任何地方访问声明为public的类成员。

声明为protected类成员可以在基类及其派生类中访问。

private成员使用关键字private后跟冒号 (:) 字符来声明。

public成员使用关键字public后跟冒号 (:) 字符来声明。

protected成员使用关键字protected后跟冒号 (:) 字符来声明。

private成员能被子类继承,但不能被子类的对象直接访问。

public成员可以在子类中被继承并被直接访问。

protected成员可以在子类中被继承并访问。

它为其数据成员提供高安全性。

它不为其数据提供任何类型的安全性。

它提供的安全性低于private访问说明符。

可以在友元功能的帮助下访问private成员。

public成员可以在有或没有友元功能的帮助下访问。

protected成员不能通过友元函数访问,它们在类之外是不可访问的,但它们可以被该类的任何子类(派生类),包括派生类及派生类的子类访问。

我们可以总结一下C++中对以上三种可见性模式的理解:

class Base {
  public:
    int x;
  protected:
    int y;
  private:
    int z;
    
};

class PublicDerived: public Base {
  // x is public and is accessible in PublicDerived class
  // y is protected and is accessible in PublicDerived class
  // z is not accessible from PublicDerived, as it is a private member of the base class
    
};

class ProtectedDerived: protected Base {
  // x is protected and is accessible in ProtectedDerived class
  // y is protected and is accessible in ProtectedDerived class
  // z is not accessible from ProtectedDerived, as it is a private member of the base class
    
};

class PrivateDerived: private Base {
  // x is private and is only accessible by the member functions of the PrivateDerived class
  // y is private and is only accessible by the member functions of the PrivateDerived class
  // z is not accessible from PrivateDerived, as it is a private member of the base class
    
};

5.结论

  • 访问说明符已用于确定该类之外的类成员(数据成员和成员函数)的可用性。

  • 在继承中,知道派生类的对象何时可以使用基类中的成员函数很重要,这称为可访问性,访问说明符用于确定这一点。

  • private、public 和protected 都是C++ 中访问说明符的类型。如果未提及或指定可见性模式,则默认情况下会考虑private模式。

  • 当类的成员被声明为 public 时,就可以从任何地方访问它们。

  • 当类中的成员被声明为protected时,它们就可以在基类和派生类中访问。

  • 当类中的成员被声明为private时,它们只能被基类的成员和友元函数访问。

  • 与public和protected访问说明符相比,private访问说明符为其数据成员提供更多的安全性。

  • 将你的类属性声明为private(尽可能经常)被认为是一种很好的做法,因为这将有助于提高数据安全性。

  • 访问修饰符主要用于数据隐藏和封装,因为它们可以帮助我们控制程序的哪一部分可以访问类的成员。这样就可以防止滥用数据。

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

C++中的private, public, protected 的相关文章

  • PubNub最佳实践:如何管理私人房间?

    我正在学习 pubnub 并阅读了他们的文档 但我只是找不到如何管理多房间聊天框 默认情况下 任何人都可以收听某个频道 订阅和发布都很容易 我想要的是拥有一个主要的公共房间 到目前为止一切都很好 但任何人都应该能够与其他人私下交谈 而不会有
  • Unity不序列化int?场地

    我有一个类想要在编辑器中更改其属性 所以我创建了我的类 System Serializable 并将我希望能够更改的变量公开 就像这样 System Serializable public class UIOptionsRing publi
  • 在没有朋友的情况下在 C++ 中测试私有类成员[重复]

    这个问题在这里已经有答案了 今天和同事讨论了课堂上要不要测试私有成员或者私有状态 他几乎说服了我为什么这是有道理的 这个问题的目的并不是重复 StackOverflow 已经存在的有关测试私有成员的性质和原因的问题 例如 让单元测试成为它正
  • Java反射带参数的私有方法最好的方法是什么?

    我正在尝试使用java反射调用私有方法我开发了一个小方法来调用其他方法迭代所有方法并按名称和参数类型进行比较我已成功调用4个方法 我有一个问题 1 这是最好的方法吗 因为我知道 class getMethod 仅匹配公共方法 Java有内置
  • 类方法如何访问同一类的另一个实例的私有成员?

    我无法理解jdk1 7中的代码 value是私有的 那么为什么代码可以使用它 例如anotherString value public final class String implements java io Serializable C
  • Java 中“私有静态最终”和“公共静态最终”类变量的最接近的 Ruby 表示形式?

    给定下面的 Java 代码 您可以最接近地表示这两个static finalRuby 类中的变量 并且 在 Ruby 中是否可以区分private static and public staticJava 中的变量 public class
  • 来自私有 GitHub 存储库的 Cordova 插件

    从私有 GitHub 存储库安装 Cordova 插件的首选方法是什么 我从供应商处购买了一个私有插件 该供应商授予我的 git 帐户访问其私有 git 存储库的权限 通常我从 cordova cli 安装插件 cordova plugin
  • 委托给私有部分

    有时 C 的隐私概念让我感到困惑 class Foo struct Bar Bar p public Bar operator gt const return p struct Foo Bar void baz std cout lt lt
  • 抽象类中受保护的抽象或公共抽象方法

    嗨 我有一个抽象类 其中有一些公共方法和一些抽象方法 我有公众 以便他们实现派生类的通用方法 让我困惑的是为什么我想要定义一个公共抽象方法而不是受保护的抽象方法 对我来说 在抽象类中定义公共抽象方法是没有意义的 因为 if 是一个抽象 在派
  • DART:扩展类中抽象方法的实现

    我在文件 myclass dart 中有两个类 abstract class A myAbstractMethod class B extends A 此时编译显示 MISSING CONCRETE IMPLEMENTATION OF一 方
  • 为什么在内部类中使用公共方法?

    我们的一个项目中有很多代码如下所示 internal static class Extensions public static string AddFoo this string s if s null return Foo return
  • 在文本框中,保护第一个单词,但允许添加/编辑这些单词之后的文本

    因此 我有一个 C 文本框 使用 NET 表单 我将在其中接受用户字符串作为某些输入 该字符串的开头已经有文本 参数 无论如何 这些文本都将存在于该字符串的开头 它一定在那里 我希望他们意识到这一点 但无法从文本框中删除这些单词 所以他们不
  • Java 中受保护的访问修饰符

    我在理解java中的受保护访问修饰符 或其背后的设计 时遇到了一些困难 我认为这意味着包访问和通过继承包含抽象成员的类的对象进行访问 我编写了以下示例代码 我发现如果未注释 注释掉的行会产生编译错误 为什么我可以通过 Second 中的 S
  • 如何对 android 进行编程以查找特定网络?

    我的应用程序仅在校园网络上才能访问校园数据 当在公共 wifi 或 3g 网络上运行应用程序时 应用程序将挂起然后强制关闭 我如何对我的应用程序进行编程以检查该专用网络 wifi或检查android当前使用的连接 如果不等于 校园wifi
  • 与受保护的内部成员的可访问性不一致

    尝试在公共类中创建受保护内部类的受保护内部成员会导致以下问题 可访问性不一致 字段类型 what Class1 ProtectedInternalClass 比字段更难访问 what Class1 SomeDataProvider data
  • Java:使用类型参数访问私有构造函数

    这是后续这个关于java私有构造函数的问题 https stackoverflow com questions 2599440 accessing the private constructor 假设我有以下课程 class Foo
  • 设计决策:为什么以及何时将接口设为私有?

    设计决策中是否使用过私有接口 如果是这样 原因是什么 您什么时候知道需要私有接口 A 顶层接口不能是私有的 它只能有public或包访问 来自Java 语言规范 第 9 1 1 节 接口修饰符 https docs oracle com j
  • 私有方法真的安全吗?

    在Java中private访问修饰符被认为是安全的 因为它在类外部不可见 那么外界也不知道这个方法 但我认为Java反射可以用来打破这个规则 考虑以下情况 public class ProtectedPrivacy private Stri
  • 防止 Visual Studio Code 或 IDE 泄露 Python 类私有方法

    只是想问一个简单的问题 本质上 我想知道是否可以从 Visual Studio Code 或其他 IDE 提供的建议列表中隐藏 Python 类私有方法 例如 假设我们有一个类 A Creating a class class A Decl
  • Java:直接从同一类的另一个实例访问私有字段

    我正在写一个equals Object obj 一个类的函数 我发现可以访问私有字段obj来自来电者 因此 不要使用 getter Odp other Odp obj if other getCollection contains ftw

随机推荐

  • TIME_WAIT连接过多的解决

    netstat n awk 39 tcp 43 43 S NF END for a in S print a S a 39 LAST ACK 1 SYN RECV 164 CLOSE WAIT 3 ESTABLISHED 655 FIN W
  • MySQL更改root密码

    情况一 记得root密码 用SET PASSWORD命令 1 打开终端win 43 r输入cmd回车即可打开 xff1b 2 通过mysql u用户名 p指定root用户登录MySQL xff0c 输入后回车会提示输入密码 3 修改MySQ
  • mac下控制台可以搜索到命令但是vscode显示zsh: command not found:

    记录下吧 困扰几天了 xff0c mac怎么这么难安这些环境变量什么的啊哈哈哈 node npm都是能搜到的 在控制台全局安装了yarn xff0c 控制台可以yarn v命令 xff0c 但是vscode报错zsh command not
  • 1.机器学习sklearn-------聚类

    1 sklearn简介 Scikit learn 也简称 s klearn 是机器学习领域当中最知名的 python 模块之一 sklearn库共分为6大部分 xff0c 分别用于完成分类任务 回归任务 聚类任务 降维任务 模型选择以及数据
  • KEIL编译报错,解决方法汇总

    目录 背景 最近在跟着野火码uCosiii的代码时 xff0c 感觉非常完美 xff0c 结果一编译 xff0c 报了120个莫名其妙的问题 xff0c 下面是踩过的坑 xff0c 一起记录下 xff0c 免得下次又掉进去了 1 编译汇编文
  • “从0开始的FreeRTOS”系列教程第一讲

    大家好 xff0c 这次给大家带来了Freertos的教程 xff0c 这次打算一口气做完一整个系列的教程 xff0c 大概更新频率会是月更 这个系列的教程的主要目的是带大家了解实时系统 real time operating system
  • 我的2013奋发突进

    先简单介绍自己 男 大专学历2012年6月毕业 期间2011 6月 2012 6 算是实习期 正式实习了一年 从2012 6月实习结束后 没打算在原来实习的单位呆着 换了一家公司 一直到2013年的7月末 考虑到种种原因 回归家乡了 技术篇
  • VR 杂想

    什么是VR VR xff08 科学技术 xff09 即VR xff08 Virtual Reality xff0c 即虚拟现实 xff0c 简称VR xff09 xff0c 是由美国VPL公司创建人拉尼尔 xff08 Jaron Lanie
  • 解决rosdep init错误和rosdep update错误以及ros密钥错误

    解决rosdep init错误和rosdep update错误以及ros密钥错误 如果仍无法解决下面所述问题 xff0c 欢迎留言 对于rosdep init错误有以下几种方法 1 更换软件源并更新软件包 sudo apt get upda
  • vscode使用技巧——webpack项目的断点调试

    为了方便调试 xff0c 我研究了一下如何使用vscode进行断点调试 本次尝试已在html template项目中测试通过 安装插件 在vscode的插件商店安装必要的插件 Debugger for Chrome 调整webpack配置
  • apt-get 源和常识

    本文内容 xff1a 1 apt get的源换成阿里或163的 2 atp get的源的常识 一 概述 安装好Ubuntu它自带源是国外的 xff0c 访问较慢 xff0c 经常会出现连接失败的情况 所以建议将它替换为国内的 xff08 如
  • 树莓派、百度DuerOS等RAW格式的镜像浏览、提取文件的方法

    前言 树莓派上装了docker等一堆东西 xff0c 要跑DuerOS的 DuerOS开发套件个人版 http open duer baidu com openduer product idk id 61 personal xff0c 有好
  • 解决Ubuntu可以ping通ip地址,不能ping通域名和浏览器无法上网的问题

    Ubuntu版本18 04 4 主要原因 原本的dns解析不行 要修改为谷歌的域名解析服务器8 8 8 8才行 并且每次关机后就会恢复默认 要添加到开机自启 1 修改配置文件 vim etc NetworkManager NetworkMa
  • Java核心技术卷1读书笔记

    Java核心技术卷1读书笔记 前言Math floorMod 前言 本笔记主要记录学习 JAVA核心技术 卷1 时遇到的问题或者心得 xff0c 若有朋友有更好的学习资源推荐请留言或联系我VX 18439428204 QQ 75107651
  • [前端基础] 浏览器篇

    提供基础用法 xff0c 基础概念引用 MDN W3C xff0c 基础内容做扩展知识 xff0c 可应对面试 xff0c 详细原理及应用需要去官网 GitHub 深入学习 1 常用 BOM 方法 BOM xff08 browser obj
  • STM32 keil5 报错:flash download failed-cortex M3解决方法

    起因 因为之前自己使用的STM32都是使用的F4 xff0c 自己打了一块STM32F1C8T6板子 xff0c 焊好之后 xff0c 打开以前正点原子的例程的时候 xff0c 出现无法烧录的情况 xff0c 总是报这样的错误 xff0c
  • Hadoop实战学习(3)-读取数据库内容

    要读取数据库中的数据 xff0c 首先需要实现一个实体类 xff0c 这个实体类部分映射数据库中要查询的表的字段 且该实体类需要实 现Writable与DBWritable两个接口 xff0c DBWritable的实现类负责查询与写入 x
  • 消失点(灭点、Vanishing Point)

    目录 定义 xff1a 性质 xff1a 消失点分为3种 一条直线的消失点是过摄影中心且平行于该直线的直线与像平面的交点 地面物体的两个消失点的连线为水平线 xff0c 提供地平线的信息 应用 xff1a 计算焦距和图像中心 求像心 求焦距
  • window.performance.timing 字段说明和主要性能指标

    window performance是W3C性能小组引入的新的API xff0c 目前IE9以上的浏览器都支持 字段说明 xff1a connectStart 和 connectEnd 分别代表TCP建立连接和连接成功的时间节点 domCo
  • C++中的private, public, protected

    0 概述 数据隐藏是C 43 43 面向对象编程的重要特征之一 xff0c 它允许我们隐藏对象内部细节即数据成员 xff0c 防止程序的函数直接访问一个类对象的内部表示 数据成员和成员函数 对类成员函数的访问限制由访问修饰符指定 访问修饰符