当前位置: 首页 > news >正文

C++ 访问控制

什么是访问控制

C++标准中定义了三种类成员访问控制符,公有的public,保护的protected,私有的private,这是在类的内部声明这三种控制符的意思


为什么需要访问控制

访问控制就是C++提供的一种用来保护类里的方法和属性的手端(保护即对谁可以调用某个方法和访问某个属性加上一个限制 如果某个对象试图调用一个它无权进行访问的函数 编译器将报错)


控制符访问特点

public成员:能被 本类的成员函数 (此类中任何类型的控制符声明的成员函数都可以访问)、友元函数、本类的对象、其派生类的成员函数 (不管是哪一种控制符声明的成员函数,都可以访问此类的public成员)

protected成员:能被 本类的成员函数(此类中任何类型的控制符声明的成员函数都可以)、 友元函数、其派生类的成员函数(不管是哪一种控制符声明的成员函数,都可以)与public成员相比 本类的对象及派生类的对象都不得访问此类protected成员

private成员:能被 本类的成员函数 (不管是哪一种控制符声明的成员函数,都可以)、友元函数访问 。 与public和protected成员相比 本类及派生类的对象 派生类的成员函数 均不可访问此类 private成员


总结:
public成员 允许类对象对public属性的类成员进行访问
protected访问属性下的类成员虽然 允许类成员函数对类成员进行访问 但是 不允许类对象及其派生类对象对其进行访问
private访问属性下的类成员只 允许本类中的成员函数对类成员进行访问 不允许本类对象,派生类对象,派生类成员函数对其进行访问

注意
1.对类的用户而言(即使用类对象实例的人 还有一种说法就是指只能看到类的头文件的人,因为设计类的人都将他写的实现文件编译成了二进制文件(在Windows下是.lib,.obj后缀的文件)通过类对象的实例 只能访问到类的public访问类型成员(成员函数或变量)
2.对类本身而言,即类的设计者,在设计类的过程中,在设计类的过程中,可以通过类的所有的成员函数(任何类型的控制符声明)或者友元函数 访问其类内部的所有访问类型的成员(函数和变量)
3.对该类的派生类而言,基类的public、protected的成员对它来说是可见的,即可以访问 ,至于派生类如何对基类的三种访问类型的成员进行访问,涉及了C++类继承的知识 接下来会进行解释


继承机制下的类成员访问控制

在继承机制中,会涉及到两层访问控制符,一层在子类派生列表中,一层在基类(派生类的内存模型分为两部分 :基类部分和派生类部分,其中基类部分是从基类继承而来的,派生类是自己定义的)

子类派生列表中的访问控制符:

在这里插入图片描述

上述子类派生列表中的访问控制符 影响的是派生类中继承自基类的基类部分成员 (函数或变量)的访问控制权限(也仅仅只有这一点影响),具体的影响为:

public继承(保持不变):派生类中继承自基类部分的成员(函数或变量)的访问控制权限和其在基类中声明的权限一样(public继承后,子类可以访问父类的public,protected成员,子类的客户(即子类外部)还是保持原有的访问权限)

protected继承(各自降低一个权限):派生类继承自基类中的public成员在派生类中变成protected权限,基类中其他成员经继承后再派生类中都变为private权限( protected继承后,子类仍可以访问父类的public,protected成员,子类的客户就不能访问这些成员了)

private继承(全部变为private成员):派生类继承自基类部分的成员(函数或变量)经继承后在派生类中的访问控制权限全部变为private成员(private继承后,子类仍可以访问父类的public,protected成员,子类的客户也不能访问这些成员了)

注意:🎯

1.不管是什么继承方式,基类的private成员其派生类都是不可以直接访问的(派生类可通过其他接口间接访问)
2.无论控制权限如何,继承方式如何,派生类会继承其基类的所有成员(包括private成员)访问权限和继承方式只决定派生类对基类成员的可访问属性
3.public,protected,private这三种继承方式,不会影响派生类成员访问基类的成员
4.不管是哪种继承方式,派生类都可以访问基类的public,protected成员


类继承结构下的访问控制 代码演示

#include <iostream>
using namespace std;

class Basic
{
public:
	string pub1;
	void BasicPubfux();
	//todopublic成员:能被 本类的任何访问属性的成员函数 、友元函数、本类的对象、其派生类的成员函数 (不管是哪一种控制符声明的成员函数,都可以访问此类的public成员)
protected:
	string pro1;
	void BasicProfux();
	//todoprotected成员:能被 本类的任何访问属性的成员函数、 友元函数、其派生类的成员函数(不管是哪一种控制符声明的成员函数,都可以)
	//todo与public成员相比 本类的对象及派生类的对象都不得访问此类protected成员

private:
	string pri1;
	void BasicPrifux();
	//todoprivate成员:能被 本类的任何访问属性的成员函数、友元函数 访问
	//todo与public和protected成员相比 本类及派生类的对象 派生类的成员函数 均不可访问此类 private成员
};

//todo基类中三种不同访问属性下的成员函数
void Basic::BasicPubfux()
{
	cout << endl;
	cout << "已进入基类Basic中的public访问类型成员函数 BasicPubfux" << endl;
	pub1 = "基类中成员访问符为 public 时 基类成员函数可访问 pub1";
	pro1 = "基类中成员访问符为 protected 时 基类成员函数可访问 pub1";
	pri1= "基类中成员访问符为 private 时 基类成员函数可访问 pub1";
	//todo允许访问本类中所有访问属性的成员 对象只允许访问此成员函数
}
void Basic::BasicProfux()
{
	cout << endl;
	cout << "已进入基类Basic中的protected访问类型成员函数 BasicProfux" << endl;
	pub1 = "基类中成员访问符为 public 时 基类成员函数可访问 pub1";
	pro1 = "基类中成员访问符为 protected 时 基类成员函数可访问 pub1";
	pri1 = "基类中成员访问符为 private 时 基类成员函数可访问 pub1";
	//todo允许访问本类中所有访问属性的成员 对象不允许访问此成员函数
}
void Basic::BasicPrifux()
{
	cout << endl;
	cout << "已进入基类Basic中的protected访问类型成员函数 BasicProfux" << endl;
	pub1 = "基类中成员访问符为 public 时 基类成员函数可访问 pub1";
	pro1 = "基类中成员访问符为 protected 时 基类成员函数可访问 pub1";
	pri1 = "基类中成员访问符为 private 时 基类成员函数可访问 pub1";
	//todo允许访问本类中所有访问属性的成员 对象不允许访问此成员函数
}


//todo派生自基类Basic的拥有三个不同类型的控制访问符的派生类Sub Sub2 Sub3
class Sub :public Basic
{
public:
	void SubPubPub();
protected:
	string SubPubPro;
private:
	string SubPubPri;
	//todo派生类  访问基类成员的控制访问符为public时 
};
class Sub2 :protected Basic
{
public:
	string SubProPub;
protected:
	void SubProPro();
private:
	string SubProPri;
};
class Sub3:private Basic
{

public:
	string SubPriPub;
protected:
	string SubPriPro;
private:
	void SubPriPri();
};


void Sub::SubPubPub()
{
	//todo子类Sub的派生列表访问控制符为public 成员SubPubPub在子类Sub中访问属性为public
	BasicPubfux();
	BasicProfux();
	BasicPrifux();//todo报错!无法访问 基类中访问属性为private的成员
	cout << "已进入子类Sub中的public访问类型 的成员函数 Subfux1" << endl;
}
void Sub2::SubProPro()
{
	//todo子类Sub的派生列表访问控制符为protected 成员SubProPro在子类Sub中访问属性为protected
	BasicPubfux();
	BasicProfux();
	BasicPrifux();//todo报错!无法访问 基类中访问属性为private的成员
	cout << "已进入子类Sub中的protected访问类型 的成员函数 Subfux2" << endl;
}
void Sub3::SubPriPri()
{
	//todo子类Sub的派生列表访问控制符为private 成员SubPriPri在子类Sub中访问属性为private
	BasicPubfux();
	BasicProfux();
	BasicPrifux();//todo报错!无法访问 基类中访问属性为private的成员
	cout << "已进入子类Sub中的private访问类型 的成员函数 Subfux3" << endl;
}


int main()
{
	Basic bas;
	bas.pub1;
	bas.BasicPubfux();
	cout << bas.pub1 << endl;//todo对象 只能访问类中访问控制符为public的成员 (包括成员和成员函数)
	
	Sub sub;
	//todo继承基类时访问控制符为public时的 子类Sub 能访问的
	sub.pub1;//基类Basic中访问属性为  public 的成员pub1
	sub.BasicPubfux();//基类Basic中访问属性为  public 的成员函数 BasicPubfux()
	sub.SubPubPub();//子类Sub中访问属性为 public  的成员函数 SubPubPub()

	Sub2 sub2;
	//todo继承基类时访问控制符为protected时的 子类Sub2 能访问的
	sub2.SubProPub;//仅有 子类Sub2中访问属性为 public  的成员函数 SubProPub()

	Sub3 sub3;
	//todo继承基类时访问控制符为private时的 子类Sub3 能访问的
	sub3.SubPriPub;//仅有 子类Sub3中访问属性为 public  的成员函数 SubPriPub()

	//todo从以上类继承时子类对基类的成员和自身成员的访问情况来看 
	//todo子类继承基类时不论是何种访问控制符 子类仅能访问基类中访问属性为 public 类型的成员和成员函数(其中基类中的protected访问属性的成员在派生后会升级为private类型的成员)
	//todo子类访问自身成员或成员函数的时候 仅能访问子类中访问属性为 public 类型的成员和成员函数

	//todo总结 
	//todopublic类型的成员 允许基类和子类自身的成员函数及对象的访问
	//todoprotected类型的成员 允许基类成员函数和子类自身的成员函数访问
	//todopublic类型的成员 只允许基类成员函数的访问
}

节选自:
C++访问控制符详解🔍

相关文章:

  • ASA842配置内网DNS欺骗测试
  • C++ 覆盖方法与重载方法
  • Ubuntu 12.04 ping 响应慢
  • C++ 静态属性和静态方法
  • C++ this指针与静态属性的关系
  • .NET I/O 学习笔记:对文件和目录进行解压缩操作
  • C++ new和delete动态分配和释放内存
  • C++ 类对象与类指针(静态和动态多态)
  • 第六天 if if…else 三木运算符
  • C++ 虚函数与多态性
  • pb11.2build8949 数据窗口dw limit有关问题
  • VS 监视功能
  • C++ 抽象类
  • C++ 运算符重载
  • 购买Microsoft Technet订阅,免费获得微软几乎所有的产品序列号“用于评估”,...
  • php的引用
  • 2017届校招提前批面试回顾
  • C++类的相互关联
  • Druid 在有赞的实践
  • Idea+maven+scala构建包并在spark on yarn 运行
  • leetcode386. Lexicographical Numbers
  • Nacos系列:Nacos的Java SDK使用
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • PHP变量
  • 分享自己折腾多时的一套 vue 组件 --we-vue
  • 紧急通知:《观止-微软》请在经管柜购买!
  • 码农张的Bug人生 - 见面之礼
  • 使用 QuickBI 搭建酷炫可视化分析
  • 算法-图和图算法
  • 写给高年级小学生看的《Bash 指南》
  • media数据库操作,可以进行增删改查,实现回收站,隐私照片功能 SharedPreferences存储地址:
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • 宾利慕尚创始人典藏版国内首秀,2025年前实现全系车型电动化 | 2019上海车展 ...
  • 积累各种好的链接
  • 容器镜像
  • 完善智慧办公建设,小熊U租获京东数千万元A+轮融资 ...
  • # 计算机视觉入门
  • #ubuntu# #git# repository git config --global --add safe.directory
  • (04)Hive的相关概念——order by 、sort by、distribute by 、cluster by
  • (04)odoo视图操作
  • (k8s中)docker netty OOM问题记录
  • (Redis使用系列) Springboot 使用Redis+Session实现Session共享 ,简单的单点登录 五
  • (WSI分类)WSI分类文献小综述 2024
  • (读书笔记)Javascript高级程序设计---ECMAScript基础
  • (分享)自己整理的一些简单awk实用语句
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (附源码)springboot 校园学生兼职系统 毕业设计 742122
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (转)EOS中账户、钱包和密钥的关系
  • . ./ bash dash source 这五种执行shell脚本方式 区别
  • .form文件_SSM框架文件上传篇
  • .mysql secret在哪_MYSQL基本操作(上)
  • .net core webapi 大文件上传到wwwroot文件夹
  • .Net Framework 4.x 程序到底运行在哪个 CLR 版本之上
  • .NET 设计模式—适配器模式(Adapter Pattern)