大话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…...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
Cursor实现用excel数据填充word模版的方法
cursor主页:https://www.cursor.com/ 任务目标:把excel格式的数据里的单元格,按照某一个固定模版填充到word中 文章目录 注意事项逐步生成程序1. 确定格式2. 调试程序 注意事项 直接给一个excel文件和最终呈现的word文件的示例,…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
Debian系统简介
目录 Debian系统介绍 Debian版本介绍 Debian软件源介绍 软件包管理工具dpkg dpkg核心指令详解 安装软件包 卸载软件包 查询软件包状态 验证软件包完整性 手动处理依赖关系 dpkg vs apt Debian系统介绍 Debian 和 Ubuntu 都是基于 Debian内核 的 Linux 发行版ÿ…...
Java如何权衡是使用无序的数组还是有序的数组
在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...
可靠性+灵活性:电力载波技术在楼宇自控中的核心价值
可靠性灵活性:电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中,电力载波技术(PLC)凭借其独特的优势,正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据,无需额外布…...
Qt Http Server模块功能及架构
Qt Http Server 是 Qt 6.0 中引入的一个新模块,它提供了一个轻量级的 HTTP 服务器实现,主要用于构建基于 HTTP 的应用程序和服务。 功能介绍: 主要功能 HTTP服务器功能: 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...
基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...
大模型多显卡多服务器并行计算方法与实践指南
一、分布式训练概述 大规模语言模型的训练通常需要分布式计算技术,以解决单机资源不足的问题。分布式训练主要分为两种模式: 数据并行:将数据分片到不同设备,每个设备拥有完整的模型副本 模型并行:将模型分割到不同设备,每个设备处理部分模型计算 现代大模型训练通常结合…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
