C++类访问控制

咱们一起学C++第九十二篇:之优化类设计与访问控制实践 在C++的学习旅程中,我们不断探索新的知识领域,每一个进步都离不开大家的共同努力。我希望通过博客分享,能与各位小伙伴一起深入理解C++的精髓。就像在黑暗中摸索时,彼此的交流和分享能成为照亮前方道路的明灯。我们一起剖析C++中的复杂概念,共同攻克学习过程中的难题,让我们的编程技能逐步提升,在C++的世界里走得更远。希望我的博客能为大家带来新的启发和帮助,一起在学习C++的道路上茁壮成长。 阅读详情

原帖如下
 1 #include <IOSTREAM>
 2 using namespace std;
 3 
 4 class A{
 5 public:
 6     A(int i_,int j_)
 7     {
 8         i=i_;
 9         j=j_;
10     }
11     void disp(A &a)
12     {
13         cout<<a.i<<endl<<a.j<<endl;
14     }
15 
16 private:
17     int i;
18 protected:
19     int j;
20 };
21 
22 int main(int argc, char* argv[])
23 {
24     A a(123,456);
25     A b(789,543);
26     a.disp(b);
27     b.disp(a);
28 
29     return 0;
30 }

 

初看起来,倒是会产生疑问。为什么会这样,是否有bug?
仔细考究起来,我们其实可以这样看待类和对象:
类是将数据成员和进行于其 上的一系列操作(成员函数)封装在一起,注意:成员函数可以操作数据成员(可以称类中的数据成员为泛数据成员)!
对象是类的实例化,怎样理解实例 化?其实每一个实例对象都只是对其中的数据成员初始化,内存映像中每个对象仅仅保留属于自己的那份数据成员副本。而成员函数对于整个类而言却是共享的,即 一个类只保留一份成员函数。
那 么每个对象怎样和这些可以认为是“分离”的成员函数发生联系,即成员函数如何操作对象的数据成员?记住this指针,无论对象通过(.)操作或者 (->)操作调用成员函数,编译时刻,编译器都会将这种调用转换成我们常见的全局函数的形式,并且多出一个参数(一般这个参数放在第一个),然后将 this指针传入这个参数。于是就完成了对象与成员函数的绑定(或联系).
实例化后就得到同一个类的多个不同的对象,既然成员函数共享的,那么成 员函数就可以操作对象的数据成员。
问题是现在有多个对象,成员函数需要知道操作的是哪个对象的数据成员?
比如有对象obj1和obj2, 都属于A类,A类有public成员函数foo()
如果obj1调用该函数,编译时会给foo函数传入this指针,obj1,foo中操作 obj1自身的成员就不用任何修饰,直接访问,因为其中的数据成员自动根据this指针找到。
如果obj1调用该函数,同样可以访问同类的其他对 象的数据成员!那么你需要做的是让foo函数知道是同类对象中哪个对象的数据成员,一个解决办法是传入同类其他对象的指针或引用,那么就可以操作同类其他 对象的数据成员。
foo(A &obj)
这样定义,然后调用:
obj1.foo(obj2)
就可以在obj1访 问obj2的数据成员,而无论这些数据成员是private还是protected

搬出C++ Object Model,可以画出各个对象的内存map就可以更清晰的看出:


总结:C++的访问修饰符的作 用是以类为单位,而不是以对象为单位。

通俗的讲,同类的对象间可以“互相访问”对方的数据成员,只不过访问途径不是直接访问.
步 骤是:通过一个对象调用其public成员函数,此成员函数可以访问到自己的或者同类其他对象的public/private/protected数据成 员和成员函数(类的所有对象共用),而且还需要指明是哪个对象的数据成员(调用函数的对象自己的成员不用指明,因为有this指针;其他对象的数据成员可 以通过引用或指针间接指明)

C++中public,protected,private访问小结
第 一:private,public,protected方法的访问范围.(public继承下)
private: 只能由该类中的函数、其友元函数访问,不能被任何其他访问,该类的对象也不能访问.
protected: 可以被该类中的函数、子类的函数、以及其友元函数访问,但不能被该类的对象访问
public: 可以被该类中的函数、子类的函数、其友元函数访问,也可以由该类的对象访问
注:友元函数包括两种:设为友元的全局函数,设为友元类中的成员函数

第 二:类的继承后方法属性变化:
使用private继承,父类的所有方法在子类中变为private;
使用protected继承,父 类的protected和public方法在子类中变为protected,private方法不变;
使用public继承,父类中的方法属性 不发生改变; 
 


public:protected:private:
public继承publicprotected---
protected继承protectedprotected---
private继承privateprivate---

protected继承和private继承能降低访问权限

再次提到:可以提供访问行为的主语为“函数”。
类体内的访问 没有访问限制一说,即private函数可以访问public/protected/private成员函数或数据成员,同理,protected函 数,public函数也可以任意访问该类体中定义的成员
public继承下,基类中的public和protected成员继承为该子类的 public和protected成员(成员函数或数据成员),然后访问仍然按类内的无限制访问


对于类域范围内,成员函数访问无所谓访问限制。
对于继承情况下的基类private成员,在派生类中仍然继承了下 来,只不过它不能直接访问,   即使在类里也不行,   更不用说是类对象了。
可以通过下列例子看到:

 1   #include  < iostream >
 2   using   namespace  std;
 3  
 4   class  C{
 5   public :
 6       C( int  val) : m_c(val) {}
 7   private :
 8        int  m_c;
 9   };
10  
11   class  D:  public  C{
12   public :
13       D( int  val1,  int  val2) : C(val1), m_d(val2) {}
14        int  m_d;
15   };
16  
17   int  main()
18   {
19  
20  
21       cout  <<   sizeof (C)  <<   "   "   <<   sizeof (D)  <<  endl; //  4  8
22       D obj( 2 ,  25 );
23       cout  <<   & obj  <<   "   "   <<   & obj.m_d  <<  endl; // 0x0012FF78   0X0012FF7C
24        // cout << obj.m_c;  // error, 不能访问
25  
26       D  * ptr  =   & obj;
27        int   * iptr  =  ( int   * )ptr;
28       cout  <<   * iptr  <<   "   "   <<   * (iptr + 1 )  <<  endl; // 2  25
29       
30        return   0 ;
31   }
32  
33  


同样,加入虚函数,可以看到VC编译器将vptr放置在数据区的最开头


 

下面这个问题摘自论坛的一个帖子 :

已知3个类O、P和Q,类O中定义了一个私有方法F1、一个公有方法F2和一个受保护的方法F3:类P和类Q是类O的派生类,其继承方式如下所示:
class P : protected O {…};
class Q : public O {…};
关于方法F1的描述 中正确的是___(34)___;关于方法F2韵描述中正确的是___(35)___;关于方法F3的描述中正确的是___(36)___。
(34)
A. 方法F1无法被访问
B.只有在类O内才能访问方法F1
C.只有在类P内才能访问方法F1
D.只有在类Q内才能访问方法F1
(35)
A.类O、P和Q的对象都可以访问方法F2
B.类P和Q的对象都可以访问方法F2
C.类0和Q的对象都可 以访问方法F2
 D.只有在类P内才能访问方法F2
(36)A.类0、P和Q的对象都可以访问方法F3
B.类0、P和Q的对 象都不可以访问方法F3
C.类0和Q的对象都可以访问方法F3
D.类P和Q的对象都可以访问方法F3。

有甚么办法可以简单地记住这许多的规则? 下文告诉你一个根本不需要记的办法。

顾名思义,private/public/protected 分别表示 私有/公开/保护,它们是一组用于访问权限 控制的关键字。 那么首先,需要澄清的一个关键点是,是要控制谁访问谁的权限 ?这个访问的主语(施事)是谁?宾语(受事)是谁?

我们经常听到这样的说法:

1)一个类友元 可以访问该类的任何成员 (包括 成员变量及成员方法,下同)。
2)private成员 只有该类自身可以访 问,protected成员 只有该类及其派生类可以访问,public成员 所 有的人都可以访问。

宾语(受事)是谁这一点很明确,是类的成员 (包括成员变量及成员方法)。主语 (施事)是谁?这是让大家发生混淆的关键点。也是这个说法中含糊不清的地方。

想清楚一点,其实主语(施事) 指的是一个函数 ,而不是类 (当 然更不是变量)。private/public/protected要控制的是一个函数(施事) 对一个类的成员(包括成员变量及成员 方法) 的访问权限。因此比较完整的说法是:

1)一个类友元(包含友元函数或者友元类的所有成员函数) 可以访问该类的任何成 员 (包括成员变量及成员方法)。

2)除去友元外,private成员 只有该类自身的成员函数 可以访 问,protected成员 只有该类的成员函数及其派生类的成员函数可以访问,public成 员 则所有的函数都可以访问。

也就是说,当我们说一个类可以访问XXX,其实暗指这个类的成员函数 可以访问XXX。了解了这一点,外加一条显而易见的规则,上面的 问题就不难回答了。这条规则是:

3)派生类在继承时可削弱成员的访问权限(通过protected/private修饰)。例如上面的例子class P : protected O {…}; 那么某个函数通过类P访问O中成员时,该函数对类O中的public成员只有protected权限。

补充:有一种技术叫Member Spy(类成员间谍),通过该技术派生类可将基类的protected成员修改为public权限。这种技术用到了using关键字。举例如下:

class A
{
protected:
 int m_data;
};

class SpyA : public A
{
public:
 using A::m_data;
};

void TestSpy(A* pA)
{
 SpyA* pSpyA = static_cast<SpyA*>(pA);
  // 强制转换A为SpyA,这要求SpyA没有成员变量且没有重载A中的虚函数。
 // 现在你可以通过pSpyA访问m_data了。例如:int data = pSpyA->m_data;
}

由于这种技术用到了强制类型转换,当谨慎使用。

VESC电调高级调参指南:电机校准与性能优化实战解析 本文详细解析了VESC电调的高级调参方法,包括电机校准与性能优化实战技巧。从基础参数设置到高级机械参数优化,再到动态性能调优,提供了全面的调参指南。特别针对电机类型、功率设置、电池参数配置等关键环节给出实用建议,帮助用户充分发挥VESC电调的性能潜力。 阅读详情

相关推荐

用deepseek部署全自动的机器人--bytebot

Bytebot是一款开源AI桌面代理,提供完整的虚拟桌面环境,支持跨应用任务处理、文件管理、文档处理等复杂工作流。其技术架构包含核心控制、LLM代理、UI等组件,支持Docker和Kubernetes部署。本文演示了基于CloudStudio的部署流程,包括环境配置、Docker部署及DeepSeek API集成,实现多模型调用功能。

Kin 2481

C++ 类成员的可访问范围

private 缺省 public protected 类成员内部可以访问私有成员。 类成员外的地方只能访问公有成员,而不能访问私有成员。 protected一般在继承的时候会用到比较多。

天高任鱼跃 495

TOPCon vs PERC:2024年光伏电站投资,哪种技术更划算?

本文深入分析了2024年光伏电站投资中TOPCon与PERC技术的财务表现。通过对比初始系统成本、全生命周期发电量及环境适应性,指出当前TOPCon组件与PERC价差已显著缩小,其更高的转换效率和更低的衰减率能有效降低度电成本并提升项目内部收益率,为投资者提供更具长期价值的方案。

p5l2m9n4o6q的博客 267

C++小知识:C++类中成员的访问控制属性有哪些类型,什么区别

public:这是公有的成员,允许类外直接访问,当然,这要加上类作用域符::, protected:这是保护成员,只允许该类及其派生类访问 private:这是私有成员,只允许在该类中进行访问,当然,在类外只可以通过设定的公有函数进行访问。

一页书DevilBox的优快云 2338

人工智能训练师认证教程(5)使用MONAI进行医学影像分析的完整指南

本文介绍了使用MONAI框架进行医学影像分析的全流程。首先详细说明了环境搭建步骤,包括PyTorch和MONAI的安装配置。然后以肺部CT 3D分割为例,分步骤讲解了数据准备与预处理、3D UNet模型构建、训练配置(DiceLoss损失函数、Adam优化器等)以及训练验证循环的实现。文章还包含推理可视化方法和模型导出为ONNX格式的部署方案,并强调了医学影像分析中的数据格式适配、强度归一化、显存优化等关键注意事项。最后指出MONAI的医学专用组件可大幅简化开发流程,建议后续可探索SwinUNETR等进阶方

华为开发者布道师,天府英才计划,致力于大数据+AI 的应用创新,助力企业与个人AI创新赋能。 1212

飞牛Docker部署Zerotier后无法访问?三步搞定SSH权限配置!

本文详细解析了在飞牛NAS上通过Docker部署Zerotier后无法访问的常见问题及解决方案。重点介绍了SSH权限配置、tun模块加载和Docker容器权限设置等关键步骤,帮助用户快速解决虚拟网络接口的权限问题,确保Zerotier节点间的正常通信。

qq_27496129的博客 797

类中成员的访问控制

华软 万沛锋(Java学生) 348

[密码学实战]密评考试训练系统v1.0程序及密评参考题库(获取路径在文末)(二十四)

本系统将密码学理论与软件工程实践相结合,为密评备考提供了高效解决方案。随着《密码法》的深入实施,掌握密评知识将成为信息安全从业者的核心竞争力。立即开始您的密码安全专家之旅!(注:实际应用请以最新发布版本为准)

曼岛_的博客 799

C++ 中 类成员可访问范围

C++ 类中成员的可访问范围 一.基本准则 1. 类的特征一是封装 public 和 private 的作用是实现这一目的 用户代码(类外) 可以访问public成员,而不能访问private 成员;而private 成员只能由类成员(类内)和友元访问。 2. 类的特征二是继承 protected 成员可以被派生类对象访问,不能被用户代码(类外)访问 二. 继承中的特点 publ...

msyyxwf的专栏 636

Calibre :Standard Verification Rule Format(SVRF) Manual (1-2)

摘要:SVRF规则文件是用于Calibre和ICverify工具的脚本文件,包含层定义、规则检查、注释、预处理指令等元素。规则文件支持全局/局部层定义、隐式层操作,以及条件编译指令(#DEFINE/#IFDEF等)。宏功能(DMACRO/CMACRO)可实现代码复用,支持参数化层操作和嵌套调用。预处理指令支持版本控制(#IFDEFCALIBRE_VERSION)和环境变量默认值设置(#PRAGMAENV)。宏中的层名具有局部作用域,可通过特殊语法实现全局层名指定,LOCAL()修饰符可创建调用作用域内的唯一

u013620135的博客 1342

matlab 异常值检测与处理——Robust Z-score法【2024最新版】

博客长期更新,本文最近一次更新时间为:2024年12月9日。

点云侠的博客 1516

C++类访问控制及继承

一、C++类的访问控制有三类:public,protected和private。 类访问控制符 类成员可被哪些对象访问 public 1、类的成员函数。2、类对象。3、友元。4、子类成员函数 protected 1、类的成员函数。2、友元。3、子类成员函数 private 1、类的成员函数。2、友元 二、C+

2192

化工过程设计软件:Aspen Plus二次开发_(2).二次开发概述

假设我们需要创建一个自定义的换热器模型,该模型能够计算两个物流之间的热交换量,并根据传热系数和换热面积进行调整。ACM 模型代码示例!自定义换热器模型!参数:传热系数 U (W/m^2·K)!换热面积 A (m^2)!热物流 T_hot_in (K), T_hot_out (K), F_hot (kmol/h)!冷物流 T_cold_in (K), T_cold_out (K), F_cold (kmol/h)!模型输入!U - 传热系数!A - 换热面积!

kkchenjj的博客 370

C++类的访问控制

前言C++类中关于访问说明符的关键字是public,protected和private,由于C++的继承的访问说明符不同,这里会牵扯出非常多不同的情况,本文尝试对此进行整理无继承public,protected和private这三个访问说明符其实是针对使用该类的代码而言的,如下class Test { public: int a; protected: int b; private:

北极星 2778

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

C++总结:类的访问控制

C++总结:类的访问控制 2019-4-12 1. 类的继承 class 派生类名: 继承方式 基类1, 继承方式 基类2... { 派生类成员声明 } 基类的构造函数和析构函数不能被派生类继承。 2.访问控制 public: 公有继承 派生类内:基类的公有成员和保护成员在派生类中的访问属性不变,仍作为派生类的公有成员和保护成员,而基类的私有成员不可被派生类成员直接访问。 派生类外:通...

左左张 931

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

C++ 类访问控制

最近在使用C++创建类的时候,忽然发现自己对于类访问控制 public,protected,private 的作用没有理解透彻,后来就查了些资料,这里以作记录。访问控制C++类的重要属性就是封装和继承。因此,最关键的问题就是权限 的问题,public,protected,private 控制的就是类内成员的访问权限。

shuzfan的专栏 2154

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

C++类的访问控制总结

用“三个4”进行C++类的访问控制总结

qq_23115737的博客 260

c++类的定义及类成员的访问控制

类的定义 在c++中,类的定义方法如下 class 类名{ 访问范围说明符: 成员变量1 成员变量2 成员函数声明1 成员函数声明2 访问范围说明符: 更多成员变量 更多成员函数声明 ... }; 类的定义要以;结束。 类的基本思想是数据抽象和封装。数据抽象是一种把接口和实现分离的编程...

as745471的博客 731

java类和C++类形式上的不同,java类的访问控制修饰符

最大的不同就是,java类的前面可以有访问控制符,即可以控制类的可见性,C++没有,所以C++所有的类的是public的。 对于java: public表示全局类,该类可以import到任何类内。 不加public默认为保留类,只能被同一个包内的其他类引用。 private只能被同个文件内的类引用,而且必须写在非private类的里面。 Student.java文件里定义了一个SchoolBag私有类, package hong; public class Student { int id; St

二进制君 828

C++类的封装和访问控制

类的封装、     1)封装是main想对象程序设计最基本的特性。把数据(属性)和函数(操作)合成一个整体,这在计算机世界中是用类和对象实现的     封装就是把客观事物封装成抽象的类,并且类可以把自己的数据和方法只让可信的类或者对象操作,对不可信的进行信息的隐藏     备注:有两层含义(把属性和方法进行封装  对属性和方法进行访问控制)     2)类成员的访问控制         ...

error0_dameng的博客 300

C++类继承的访问控制权限

《C++Primer》中15.5一节,有关于访问控制与继承的介绍,但是不知是翻译的问题还是介绍顺序的问题,总觉得理解起来不是特别清晰,现对C++的类继承与访问控制权限做一个总结,如有不准确之处还望指正。    一、一个类的访问说明符 先介绍基础内容,一个类可以用访问说明符来封装自己的数据成员和函数成员,一共有三种访问说明符,public,private,protected。这些说明符,对于

weixin_37730368的博客 598

C++ 类的访问控制01

C++类的访问控制

月山知了的博客 187

C++类的访问控制限定符

文章目录C++类的访问控制限定符 C++类的访问控制限定符 public:公有成员,在任何位置都可以访问 private:私有成员,只能类(自己)的成员函数中访问 protected:受保护成员,只能在类(自己)和子类中访问 注意:类中的成员变量、成员函数默认是 private,结构中的成员变量、成员函数默认是 public。 注意:C++中类和结构的区别只有成员函数和成员变量默认访问权限不同。 ...

zgdzjzz的博客 671

C++笔记——类的继承和访问控制

C++中类的继承的语法如下: 首先定义一个基类(父类),然后定义派生类(子类)继承基类,语法如下         class 派生类名:访问控制符 基类名 访问控制符包括以下三种: 1>public:修饰的成员变量或方法,在类的内部和类的外部都能被访问         2>protected:修饰的成员变量或方法,只能在类的内部或者继承的子类中访问,不能在类的外部访问    

sunny0917的博客 432

咱们一起学C++第三篇:之探秘类的访问控制与实现隐藏

在C++的学习道路上,我们一起前行,每一步都充满挑战与惊喜。前两篇我们了解了面向对象程序设计的基本概念、对象与类的特性,今天我们将聚焦于类的访问控制和实现隐藏这一重要特性,它对于构建健壮、可维护的程序至关重要。

wj_rdk的博客 1394

C++-Record15—类的封装和访问控制

介绍类的封装及访问控制相关的概念

恋蛩音的博客 524
上一篇: 关于常量引用
下一篇: hpbasic
codexy
博客等级 码龄17年 25粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值