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

C++快速理解之封装

c++
成员访问限定符private、protected、public

1.是什么?

一种权限标记,就是你能不能使用该类中的成员

2.为什么要用?

一个对象,由很多数据(成员变量)+很多函数(成员函数)组成,有些时候定义的成员变量数据比较重要,
不想通过对象.成员变量=xxx或对象指针->成员变量=xxx的方式直接修改,此时我们就需要使用到权限的限定

就好比我们都是一家人可以用公用的数据,对外人是不能用的

3.三种方式

通过 public、protected、private 三个关键字来控制成员变量和成员函数的访问权限,被称为成员访问限定符

public:公有的
protected:受保护的
private:私有的

在类的内部(定义类的代码内部),无论成员被声明为 public、protected 还是 private,都是可以互相访问的,没有访问权限的限制

在类的外部(定义类的代码之外),只能通过对象或指针访问public修饰的成员,不能访问 private、protected 修饰的成员

#include <iostream>using namespace std;class Student {
private:char *name;int age;float score;public:// 成员函数的定义void set_name(char *name) {this->name = name;}void set_age(int age) {this->age = age;}void set_score(float score) {this->score = score;}void show() {cout << this->name << "的年龄是" << this->age << ",成绩是" << this->score << endl;}
};int main() {// 在栈上创建对象Student stu;stu.set_name("张三");stu.set_age(15);stu.set_score(92.5f);
//    cout << stu.name << "\n";  // 失败,因为name是私有的,不能在类的外部通过对象访问stu.show();// 在堆上创建对象Student *pstu = new Student;pstu->set_name("李四");pstu->set_age(16);pstu->set_score(96);
//    cout << pstu->name << "\n";  // 失败,因为name是私有的,不能在类的外部通过对象访问pstu->show();return 0;
}

在这里插入图片描述

4.成员变量

成员变量,说到底就是对象的一些可以用来存储数据的变量而已,如果不希望通过外部使用这些变量,就private修饰

5.成员函数

成员函数,说到底就是对象的一些可以调用的函数而已

如果希望通过外部调用这个函数,就用 public 修饰
如果不希望外部调用这个函数,那么就 private 修饰
还有一种情况,如果定义了private成员变量,那么可以定义对应的public成员函数,这样做的好处

这个私有的成员变量,不能直接通过外部对象访问,但是可以通过这个公有的函数间接访问
一般给某个私有的成员变量,创建对应的2个公有成员函数

给成员变量赋值的函数通常称为 set 函数,它们的名字通常以set开头,后跟成员变量的名字
读取成员变量的值的函数通常称为 get 函数,它们的名字通常以get开头,后跟成员变量的名字

6.总结
这种将成员变量声明为 private、将部分成员函数声明为 public 的做法体现了类的封装性

所谓封装,是指尽量隐藏类的内部实现,只向用户提供有用的成员函数

额外添加 set 函数和 get 函数多麻烦,直接将成员变量设置为 public 多省事!确实,这样做 99.9% 的情况下都不是一种错误,我也不认为这样做有什么不妥;但是,将成员变量设置为 private 是一种软件设计规范,尤其是在大中型项目中,还是尽量遵守这一原则

PS:
注意
private 后面的成员都是私有的,直到有 public 出现才会变成共有的;
public 之后再无其他限定符,所以 public 后面的成员都是共有的;
private 的成员和 public 的成员的次序任意,既可以先出现 private 部分,也可以先出现 public 部分;
如果既不写 private 也不写 public,就默认为 private;
在一个类体中,private 和 public 可以分别出现多次;
每个部分的有效范围到出现另一个访问限定符或类体结束时(最后一个右花括号)为止。但是为了使程序清晰,应该养成这样的习惯,使每一种成员访问限定符在类定义体中只出现一次;

下面的类声明也是完全正确的:

class Student{
private:char *m_name;
private:int m_age;float m_score;
public:void setname(char *name);void setage(int age);
public:void setscore(float score);void show();
};

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 使用开源 LLM 充当 LangChain 智能体
  • 【C++】5.类和对象(3)
  • 算法训练(leetcode)第四十六天 | 110. 字符串接龙、105. 有向图的完全可达性、106. 岛屿的周长
  • Oracle数据库巡检 - RAC巡检
  • Java常见面试题-11-MongoDb
  • 非线性表之堆的实际应用和二叉树的遍历
  • 三数之和与四数之和 | LeetCode-15 | LeetCode-18 | 双指针 | 降维 | 哈希集合 | Java | 详细注释
  • Hive3:数据的加载与导出
  • 算法板子:欧拉函数——求一个数的欧拉函数、线性时间内求1~n所有数的欧拉函数
  • 宝兰德JVM参数查看及优化
  • 使用ubuntu串口数据收和发不一致问题
  • SpringAOP面向切面编程的概念和使用
  • 萱仔求职系列——1.1 机器学习基础知识复习
  • Redisson 实现分布式锁
  • vue2项目微信小程序的tabs切换效果
  • [译] 理解数组在 PHP 内部的实现(给PHP开发者的PHP源码-第四部分)
  • [译]Python中的类属性与实例属性的区别
  • CAP理论的例子讲解
  • JS变量作用域
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • PV统计优化设计
  • vue的全局变量和全局拦截请求器
  • 从PHP迁移至Golang - 基础篇
  • 区块链共识机制优缺点对比都是什么
  • 容器化应用: 在阿里云搭建多节点 Openshift 集群
  • 微信端页面使用-webkit-box和绝对定位时,元素上移的问题
  • 线上 python http server profile 实践
  • NLPIR智能语义技术让大数据挖掘更简单
  • Play Store发现SimBad恶意软件,1.5亿Android用户成受害者 ...
  • 昨天1024程序员节,我故意写了个死循环~
  • ​Redis 实现计数器和限速器的
  • ​草莓熊python turtle绘图代码(玫瑰花版)附源代码
  • ​渐进式Web应用PWA的未来
  • ​业务双活的数据切换思路设计(下)
  • #QT 笔记一
  • #我与Java虚拟机的故事#连载05:Java虚拟机的修炼之道
  • (c语言)strcpy函数用法
  • (javascript)再说document.body.scrollTop的使用问题
  • (leetcode学习)236. 二叉树的最近公共祖先
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (转)LINQ之路
  • (转)MVC3 类型“System.Web.Mvc.ModelClientValidationRule”同时存在
  • (转载)Google Chrome调试JS
  • .NET CORE Aws S3 使用
  • .NET Core 实现 Redis 批量查询指定格式的Key
  • .NET MAUI Sqlite程序应用-数据库配置(一)
  • .NET/C# 使窗口永不激活(No Activate 永不获得焦点)
  • .NET项目中存在多个web.config文件时的加载顺序
  • @Responsebody与@RequestBody
  • []C/C++读取串口接收到的数据程序
  • [2024-06]-[大模型]-[Ollama]- WebUI
  • [Angular] 笔记 9:list/detail 页面以及@Output
  • [cogs2652]秘术「天文密葬法」
  • [Doc][px4][ros2][gazebo][yolov8]PX4-ROS2-Gazebo-YOLOv8
  • [E链表] lc83. 删除排序链表中的重复元素(单链表+模拟)