大话C++:第11篇 类的定义与封装
1 类的定义
在C++中,类的定义通常使用class
关键字开始,后面紧跟类的名称。类可以包含数据成员(变量)和成员函数(方法)。
在C++中,类可以更加详细地展开,包括数据成员(变量)的声明、成员函数的声明与定义、构造函数、析构函数、内联成员函数、静态成员、友元函数等。类定义的语法格式:
// ClassName类名
class ClassName
{
public:// 公共构造函数ClassName(); // 默认构造函数ClassName(const ClassName& other); // 拷贝构造函数~ClassName(); // 析构函数// 公共成员函数(包括内联函数)void publicFunction();void anotherPublicFunction() const; // const成员函数static void staticPublicFunction(); // 静态成员函数// 公共成员变量(通常不推荐,因为破坏了封装性)int publicVariable;// 友元函数和友元类friend void friendFunction(ClassName& obj);friend class FriendClass;protected:// 受保护成员函数void protectedFunction();// 受保护成员变量int protectedVariable;private:// 私有成员函数void privateFunction();// 私有成员变量int privateVariable;// 私有静态成员变量static int privateStaticVariable;// 私有静态成员函数static void privateStaticFunction();// 类内定义成员函数(内联函数)inline void inlineFunction() {// 函数体}// 类的嵌套类class NestedClass {// NestedClass 的定义};
};
其中,
-
构造函数和析构函数用于对象的初始化和清理。
-
成员函数可以是公共的、受保护的或私有的。
-
静态成员(函数和变量)属于类本身,而不是类的任何特定对象。
-
友元函数和友元类可以访问类的私有和保护成员。
-
内联函数通过在调用点插入函数体的复制品来提高执行速度,适合函数体简短且调用频繁的情况。
-
嵌套类是在另一个类内部定义的类。
类的定义通常放在头文件中,类的实现放在源码文件cpp。例如,学生的定义与实现
-
student.h学生类的定义
// student.h
#ifndef __STUDENT_H__
#define __STUDENT_H__#include <string>class Student
{
public:// 构造函数Student(const std::string& name, int age, int num);// 析构函数~Student();// 公共成员函数void DisplayInfo() const;// 获取成员变量的函数// 获取姓名inline std::string GetName() const;// 获取年龄inline int GetAge() const;// 获取学号inline int GetNum() const;// 设置成员变量的函数// 设置姓名inline void SetName(const std::string& name);// 设置年龄inline void SetAge(const int age);// 设置学号inline void SetNum(const int num);private:// 私有成员变量std::string _name; // 姓名int _age; // 年龄int _num; // 学号
};#endif // __STUDENT_H__
-
student.cpp学生类的实现
// student.cpp
#include "student.h"
#include <iostream>// 构造函数
Student::Student(const std::string& name, int age, int num) : _name(name), _age(age), _num(num)
{std::cout << "Student构造函数" << std::endl;
}// 析构函数(在这个简单的例子中,析构函数是空的)
Student::~Student()
{std::cout << "Student析构函数" << std::endl;
}// 显示学生信息
void Student::DisplayInfo() const
{std::cout << "该学生姓名:" << _name << ",年龄:" << _age << ",学号:" << _num << std::endl;
}// 获取学生姓名
std::string Student::GetName() const
{return _name;
}// 获取年龄
int Student::GetAge() const
{return _age;
}// 获取学号
int Student::GetNum() const
{return _num;
}// 设置姓名
void Student::SetName(const std::string& name)
{_name = name;
} // 设置年龄
void Student::SetAge(const int age)
{_age = age;
}// 设置学号
void Student::SetNum(const int num)
{_num = num;
}
-
main.cpp学生对象的定义及使用
// main.cpp
#include <iostream>
#include "student.h"int main()
{// 创建学生对象Student student("Jack", 25);// 调用成员函数student.DisplayInfo();std::cout << "该学生对象的名字: " << student.GetName() << std::endl;// 修改学生年龄student.SetAge(22);// 再次调用成员函数student.DisplayInfo();return 0;
}
2 类的封装
C++ 类的封装是面向对象编程中的一个核心概念,它指的是将数据(成员变量)和行为(成员函数)结合在一起的机制,并隐藏内部实现细节,只暴露出一个可以被外界访问和使用的接口。封装可以提高安全性和易于维护,因为它限制了对类内部数据的直接访问,只允许通过类提供的成员函数来操作数据。
为了实现封装,C++提供了访问修饰符(public
、private
、protected
)来控制类成员的访问权限。访问修饰符对类、派生类及对象具有不同的访问权限,如下表所示:
访问修饰符 | 类内部 | 派生类内部 | 对象(外部) | 示例 |
---|---|---|---|---|
public | 可访问 | 可访问 | 可访问 | 成员在类的外部和内部都可以被访问。 |
private | 可访问 | 不可访问 | 不可访问 | 成员只能在类的内部被访问,对象和派生类都无法直接访问 |
protected | 可访问 | 可访问 | 不可访问 | 成员在类的内部和派生类中可以被访问,但对象无法直接访问 |
#include <iostream>class Person
{
public:void SetName(const std::string& name) { // 公有成员函数_name = name;}std::string GetName() const { // 公有成员函数return _name;}protected:// 受保护成员函数void SetAge(int age) {_age = age;} protected:// 受保护成员变量int _age; private:// 私有成员变量 std::string _name;
};int main()
{Person person;// 对象无法直接访问私有成员// person._name = "Alice";// 对象可以访问公有成员函数person.SetName("Jack");std::cout << person.GetName() << std::endl;// 对象无法直接访问受保护成员// person._age = 10; // 错误:受保护成员无法访问return 0;
}
3 类的访问修饰符
在C++中,类的访问修饰符主要用于控制类成员(包括数据成员和成员函数)的访问权限。这些修饰符主要有四种:public
、protected
、private
和默认的default
。其中,
-
public(公共访问修饰符):
-
访问权限:最高级别的访问权限。
-
作用:允许类的任何对象以及任何其他代码访问该类的成员(无论是数据成员还是成员函数)。
-
使用场景:通常用于提供类的外部接口,即允许外部代码调用的成员函数或访问的数据成员。
-
-
protected(受保护的访问修饰符):
-
访问权限:次高级别的访问权限。
-
作用:允许类的对象、派生类(子类)以及类的内部代码访问该类的成员。
-
使用场景:通常用于实现继承时,在基类中定义一些需要被子类访问但不需要被外界访问的成员。
-
-
private(私有的访问修饰符):
-
访问权限:最低级别的访问权限。
-
作用:只允许类的内部代码访问该类的成员。
-
使用场景:通常用于隐藏类的内部实现细节,确保数据的封装性。
-
-
default(默认访问修饰符):
-
访问权限:包(package)级别的访问权限。
-
作用:允许同一包(package)中的其他类访问该类的成员,但不允许包外的类访问。
-
表格形式总结一下,详见下表:
访问修饰符 | 访问权限 | 类内部 | 派生类内部 | 类的对象 | 同包其他类 | 说明 |
---|---|---|---|---|---|---|
public | 公有 | 可访问 | 可访问 | 可访问 | 可访问 | 允许外部访问 |
protected | 受保护 | 可访问 | 可访问 | 不可访问 | 不可访问 | 允许派生类访问 |
private | 私有 | 可访问 | 不可访问 | 不可访问 | 不可访问 | 仅允许类内部访问 |
注意:在C++中,没有明确的default
关键字来表示包私有访问,这里的default
仅用于类比,代表类内部和同一包内其他类可以访问,但对象和包外类无法访问。在C++中,如果一个成员没有被显式声明为public
、protected
或private
,那么它的访问级别就是private
。
相关文章:
大话C++:第11篇 类的定义与封装
1 类的定义 在C中,类的定义通常使用class关键字开始,后面紧跟类的名称。类可以包含数据成员(变量)和成员函数(方法)。 在C中,类可以更加详细地展开,包括数据成员(变量&…...

六种主流ETL工具的比较与Kettle的实践练习指南--MySQL、hive、hdfs等之间的数据迁移
在数据集成和数据仓库建设中,ETL(Extract, Transform, Load)工具扮演着至关重要的角色。本文将对六种主流ETL工具进行比较,并深入探讨Kettle的实践应用。 一、六种主流ETL工具比较 1. DataPipeline 设计及架构:专为…...
一天一道算法题day07
找出字符中第一个匹配的下标 题目描述 给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle 不是 haystack 的一部分,则返回 -1 。 示例 1&#…...

电机学习-有感BLDC开环控制(六步换相)
文章目录 1. 简介2. 六步换向控制3. 机械角度和电角度4.转子位置获取5.霍尔传感器读取测试6.速度开环控制6.1 PWM设置6.2死区时间 1. 简介 BLDC的反电动势一般是梯形的反电动势,所以采用方波控制。如图2-1所示,是一个简化的内转子无刷直流电机。我们通过…...

《深度学习》PyTorch框架 优化器、激活函数讲解
目录 一、深度学习核心框架的选择 1、TensorFlow 1)概念 2)优缺点 2、PyTorch 1)概念 2)优缺点 3、Keras 1)概念 2)优缺点 4、Caffe 1)概念 2)优缺点 二、pytorch安装 1、安装 2、…...

Linux:进程(四)
目录 一、进程优先级 二、Linux调度与切换 1.背景 2.进程切换 一、进程优先级 背景:在计算机中,软硬件资源是有限的,而进程想要访问某一种资源,就得通过排队来保证访问资源的过程是有条不紊的。 Linux下对优先级的定义。执行命…...

CTC loss 博客转载
论文地址: https://www.cs.toronto.edu/~graves/icml_2006.pdf 为了对应这个图,我们假设一种符合的模型情况: 英文OCR,37个类别(26个小写字母10个汉字空格),最大输出长度8个字符 模型预测结果…...

TryHackMe 第3天 | Pre Security (中)
该学习路径讲解了网络安全入门的必备技术知识,比如计算机网络、网络协议、Linux命令、Windows设置等内容。上一篇中简短介绍了计算机网络相关的知识,本篇博客将记录 网络协议 部分。 How the web works? DNS in detail DNS (Domain name system&…...
c语言中“qsort函数”和“结构体成员访问变量”
qsort函数: qsort是c语言中的库函数,这个函数是对数据进行排序(对任意) 冒泡排序中排列整数顺序用的函数只适用于整形,而qsort函数适用与所有数据 排序算法 冒泡排序 插入 选择 快速 void qsort{ void * base&…...
【MySQL】在MySQL中STR_TO_DATE()
1.在MySQL中STR_TO_DATE() 在MySQL中,STR_TO_DATE() 函数用于将字符串转换为日期格式。这个函数非常有用,当你需要将文本数据转换为可由MySQL日期和时间函数处理的格式时。 1.1 语法 STR_TO_DATE() 函数的基本语法如下: STR_TO_DATE(date…...

PCIE集成验证(五)MSI/MSI-X中断
PCI 总线最早采用的中断机制是 INTx,这是基于边带信号的。后续的 PCI/PCI-X版本,为了消除边带信号,降低系统的硬件设计复杂度,逐渐采用了 MSI(Message Signaled Interrupt)/MSI-X(消息信号中断)的中断机制。…...
leetcode 380.O(1) 时间插入、删除和获取随机元素
实现RandomizedSet 类: RandomizedSet() 初始化 RandomizedSet 对象bool insert(int val) 当元素 val 不存在时,向集合中插入该项,并返回 true ;否则,返回 false 。bool remove(int val) 当元素 val 存在时࿰…...
基于MicroPython的ESP8266控制PS2摇杆模块的设计方案
以下是一个基于MicroPython的ESP8266控制PS2摇杆模块的设计方案: 一、硬件准备: 1. 一块ESP8266开发板,如NodeMCU 2. 一个带有X、Y轴模拟输出和Z轴(按钮)数字输出的PS2摇杆模块 3. 杜邦线若干 4. 3.3V直流电源 二、硬件连接:…...

Spring Boot 3项目使用Swagger3教程
Spring Boot 3项目使用Swagger3教程 Swagger:自动生成接口文档 添加依赖(pom.xml) <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-jakarta-spring-boot-starter</artifactId><version>4.1…...
linux-系统备份与恢复-系统恢复
Linux 系统备份与恢复:系统恢复 1. 概述 Linux 系统的恢复是系统管理的重要组成部分,它指的是在系统崩溃、硬件故障、误操作或安全问题后,恢复系统到可用状态的过程。良好的系统恢复计划可以有效避免数据丢失和业务中断,并确保系…...
【Rust语言】std::collections::HashMap用法
HashMap用法文档 文章目录 创建键的要求 增删改查增: insert删: remove/remove_entry改单点修改 get_mut整体修改 values_mut/iter_mut 查集增改于一身的entry 遍历只读遍历into_values() 与 into_keys()容量、实际长度、判空导出清除重定容量 use std::collections::HashMap;创…...

使用SoapUI、Postman工具调用Webservice方法
SoapUI工具更适合调用Webservice使用。 1.使用SoapUI工具调用Webservice 创建“New SOAP Project” 自行定义一个项目名称,输入wsdl地址: 在左侧列表找到方法名,双击“Request 1”, 在请求数据中,添加对应的参数,然…...
js 与 C++引用和指针的关系
js 与 C引用和指针的关系 js 中既有引用的影子, 也有指针的影子。 1、引用用法 这里相当于C 中的引用, b是a的引用, 修改b ,a也改变。 var a { 1: 1 }var b a;a null;b[2] 2;console.error(b); // { 1: 1, 2: 2 }2、指针用法 这里 a,b应该按照指针理解。 var a undef…...

python --PyAibote自动化
官文: https://www.pyaibote.com/ 下载安卓集成环境: 可以看到开发的一些信息...
Ubuntu系统开发环境搭建
一,Android源码编译环境搭建 1 安装Java Development Kit (JDK) sudo apt-get update sudo apt-get install openjdk-8-jdk 2,确认JDK安装成功 java -version 3,安装编译所需的依赖项 sudo apt-get install git-core gnupg flex bison gperf build-essential zip cu…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...

【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

23-Oracle 23 ai 区块链表(Blockchain Table)
小伙伴有没有在金融强合规的领域中遇见,必须要保持数据不可变,管理员都无法修改和留痕的要求。比如医疗的电子病历中,影像检查检验结果不可篡改行的,药品追溯过程中数据只可插入无法删除的特性需求;登录日志、修改日志…...

【机器视觉】单目测距——运动结构恢复
ps:图是随便找的,为了凑个封面 前言 在前面对光流法进行进一步改进,希望将2D光流推广至3D场景流时,发现2D转3D过程中存在尺度歧义问题,需要补全摄像头拍摄图像中缺失的深度信息,否则解空间不收敛…...
数据链路层的主要功能是什么
数据链路层(OSI模型第2层)的核心功能是在相邻网络节点(如交换机、主机)间提供可靠的数据帧传输服务,主要职责包括: 🔑 核心功能详解: 帧封装与解封装 封装: 将网络层下发…...
【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分
一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计,提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合:各模块职责清晰,便于独立开发…...
Web 架构之 CDN 加速原理与落地实践
文章目录 一、思维导图二、正文内容(一)CDN 基础概念1. 定义2. 组成部分 (二)CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 (三)CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 …...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...
C++.OpenGL (14/64)多光源(Multiple Lights)
多光源(Multiple Lights) 多光源渲染技术概览 #mermaid-svg-3L5e5gGn76TNh7Lq {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-3L5e5gGn76TNh7Lq .error-icon{fill:#552222;}#mermaid-svg-3L5e5gGn76TNh7Lq .erro…...

[免费]微信小程序问卷调查系统(SpringBoot后端+Vue管理端)【论文+源码+SQL脚本】
大家好,我是java1234_小锋老师,看到一个不错的微信小程序问卷调查系统(SpringBoot后端Vue管理端)【论文源码SQL脚本】,分享下哈。 项目视频演示 【免费】微信小程序问卷调查系统(SpringBoot后端Vue管理端) Java毕业设计_哔哩哔哩_bilibili 项…...