C++数据封装以及定义结构的详细讲解鸭~
名字:阿玥的小东东
博客主页:阿玥的小东东的博客_CSDN博客-python&&c++高级知识,过年必备,C/C++知识讲解领域博主
目录
定义结构
访问结构成员
结构作为函数参数
指向结构的指针
typedef 关键字
C++ 数据封装
数据封装的实例
设计策略
C++ 类 & 对象
C++ 类定义
定义 C++ 对象
访问数据成员
写在最后
先介绍一个字符串比较函数:strcmp(s1,s2),当s1<s2时,返回一个负整数;当s1=s2时,返回值为0;当s1>s2时,返回一个正整数
还有一个字符串复制函数:strcpy(a,b),表示将字符串b的值复制给字符串a当然字符串b的长度不能超过字符串a
定义结构
为了定义结构,您必须使用 struct 语句。struct 语句定义了一个包含多个成员的新的数据类型,struct 语句的格式如下:
struct type_name {
member_type1 member_name1;
member_type2 member_name2;
member_type3 member_name3;
.
.
} object_names;
type_name 是结构体类型的名称,member_type1 member_name1 是标准的变量定义,比如 int i; 或者 float f; 或者其他有效的变量定义。在结构定义的末尾,最后一个分号之前,您可以指定一个或多个结构变量,这是可选的。下面是声明一个结构体类型 Books,变量为 book:
struct Books
{char title[50];char author[50];char subject[100];int book_id;
} book;
访问结构成员
为了访问结构的成员,我们使用成员访问运算符(.)。成员访问运算符是结构变量名称和我们要访问的结构成员之间的一个句号。
下面的实例演示了结构的用法:
#include <iostream>
#include <cstring>using namespace std;// 声明一个结构体类型 Books
struct Books
{char title[50];char author[50];char subject[100];int book_id;
};int main( )
{Books Book1; // 定义结构体类型 Books 的变量 Book1Books Book2; // 定义结构体类型 Books 的变量 Book2// Book1 详述strcpy( Book1.title, "C++ 教程");strcpy( Book1.author, "Runoob"); strcpy( Book1.subject, "编程语言");Book1.book_id = 12345;// Book2 详述strcpy( Book2.title, "CSS 教程");strcpy( Book2.author, "Runoob");strcpy( Book2.subject, "前端技术");Book2.book_id = 1234556;// 输出 Book1 信息cout << "第一本书标题 : " << Book1.title <<endl;cout << "第一本书作者 : " << Book1.author <<endl;cout << "第一本书类目 : " << Book1.subject <<endl;cout << "第一本书 ID : " << Book1.book_id <<endl;// 输出 Book2 信息cout << "第二本书标题 : " << Book2.title <<endl;cout << "第二本书作者 : " << Book2.author <<endl;cout << "第二本书类目 : " << Book2.subject <<endl;cout << "第二本书 ID : " << Book2.book_id <<endl;return 0;
}
实例中定义了结构体类型 Books 及其两个变量 Book1 和 Book2。当上面的代码被编译和执行时,它会产生下列结果:
第一本书标题 : C++ 教程 第一本书作者 : Runoob 第一本书类目 : 编程语言 第一本书 ID : 12345 第二本书标题 : CSS 教程 第二本书作者 : Runoob 第二本书类目 : 前端技术 第二本书 ID : 1234556
结构作为函数参数
您可以把结构作为函数参数,传参方式与其他类型的变量或指针类似。您可以使用上面实例中的方式来访问结构变量:
#include <iostream>
#include <cstring>using namespace std;
void printBook( struct Books book );// 声明一个结构体类型 Books
struct Books
{char title[50];char author[50];char subject[100];int book_id;
};int main( )
{Books Book1; // 定义结构体类型 Books 的变量 Book1Books Book2; // 定义结构体类型 Books 的变量 Book2// Book1 详述strcpy( Book1.title, "C++ 教程");strcpy( Book1.author, "Runoob"); strcpy( Book1.subject, "编程语言");Book1.book_id = 12345;// Book2 详述strcpy( Book2.title, "CSS 教程");strcpy( Book2.author, "Runoob");strcpy( Book2.subject, "前端技术");Book2.book_id = 1234556;// 输出 Book1 信息printBook( Book1 );// 输出 Book2 信息printBook( Book2 );return 0;
}
void printBook( struct Books book )
{cout << "书标题 : " << book.title <<endl;cout << "书作者 : " << book.author <<endl;cout << "书类目 : " << book.subject <<endl;cout << "书 ID : " << book.book_id <<endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
书标题 : C++ 教程 书作者 : Runoob 书类目 : 编程语言 书 ID : 12345 书标题 : CSS 教程 书作者 : Runoob 书类目 : 前端技术 书 ID : 1234556
指向结构的指针
您可以定义指向结构的指针,方式与定义指向其他类型变量的指针相似,如下所示:
struct Books *struct_pointer;
现在,您可以在上述定义的指针变量中存储结构变量的地址。为了查找结构变量的地址,请把 & 运算符放在结构名称的前面,如下所示:
struct_pointer = &Book1;
为了使用指向该结构的指针访问结构的成员,您必须使用 -> 运算符,如下所示:
struct_pointer->title;
让我们使用结构指针来重写上面的实例,这将有助于您理解结构指针的概念:
#include <iostream>
#include <cstring>using namespace std;
void printBook( struct Books *book );struct Books
{char title[50];char author[50];char subject[100];int book_id;
};int main( )
{Books Book1; // 定义结构体类型 Books 的变量 Book1Books Book2; // 定义结构体类型 Books 的变量 Book2// Book1 详述strcpy( Book1.title, "C++ 教程");strcpy( Book1.author, "Runoob"); strcpy( Book1.subject, "编程语言");Book1.book_id = 12345;// Book2 详述strcpy( Book2.title, "CSS 教程");strcpy( Book2.author, "Runoob");strcpy( Book2.subject, "前端技术");Book2.book_id = 1234556;// 通过传 Book1 的地址来输出 Book1 信息printBook( &Book1 );// 通过传 Book2 的地址来输出 Book2 信息printBook( &Book2 );return 0;
}
// 该函数以结构指针作为参数
void printBook( struct Books *book )
{cout << "书标题 : " << book->title <<endl;cout << "书作者 : " << book->author <<endl;cout << "书类目 : " << book->subject <<endl;cout << "书 ID : " << book->book_id <<endl;
}
当上面的代码被编译和执行时,它会产生下列结果:
书标题 : C++ 教程 书作者 : Runoob 书类目 : 编程语言 书 ID : 12345 书标题 : CSS 教程 书作者 : Runoob 书类目 : 前端技术 书 ID : 1234556
typedef 关键字
下面是一种更简单的定义结构的方式,您可以为创建的类型取一个"别名"。例如:
typedef struct Books {char title[50];char author[50];char subject[100];int book_id; }Books;
现在,您可以直接使用 Books 来定义 Books 类型的变量,而不需要使用 struct 关键字。下面是实例:
Books Book1, Book2;
您可以使用 typedef 关键字来定义非结构类型,如下所示:
typedef long int *pint32;pint32 x, y, z;
x, y 和 z 都是指向长整型 long int 的指针。
C++ 数据封装
所有的 C++ 程序都有以下两个基本要素:
- 程序语句(代码):这是程序中执行动作的部分,它们被称为函数。
- 程序数据:数据是程序的信息,会受到程序函数的影响。
封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。
数据封装是一种把数据和操作数据的函数捆绑在一起的机制,数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。
C++ 通过创建类来支持封装和数据隐藏(public、protected、private)。我们已经知道,类包含私有成员(private)、保护成员(protected)和公有成员(public)成员。默认情况下,在类中定义的所有项目都是私有的。例如:
class Box
{public:double getVolume(void){return length * breadth * height;}private:double length; // 长度double breadth; // 宽度double height; // 高度
};
变量 length、breadth 和 height 都是私有的(private)。这意味着它们只能被 Box 类中的其他成员访问,而不能被程序中其他部分访问。这是实现封装的一种方式。
为了使类中的成员变成公有的(即,程序中的其他部分也能访问),必须在这些成员前使用 public 关键字进行声明。所有定义在 public 标识符后边的变量或函数可以被程序中所有其他的函数访问。
把一个类定义为另一个类的友元类,会暴露实现细节,从而降低了封装性。理想的做法是尽可能地对外隐藏每个类的实现细节。
数据封装的实例
C++ 程序中,任何带有公有和私有成员的类都可以作为数据封装和数据抽象的实例。请看下面的实例:
#include <iostream>
using namespace std;class Adder{public:// 构造函数Adder(int i = 0){total = i;}// 对外的接口void addNum(int number){total += number;}// 对外的接口int getTotal(){return total;};private:// 对外隐藏的数据int total;
};
int main( )
{Adder a;a.addNum(10);a.addNum(20);a.addNum(30);cout << "Total " << a.getTotal() <<endl;return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Total 60
上面的类把数字相加,并返回总和。公有成员 addNum 和 getTotal 是对外的接口,用户需要知道它们以便使用类。私有成员 total 是对外隐藏的,用户不需要了解它,但它又是类能正常工作所必需的。
设计策略
通常情况下,我们都会设置类成员状态为私有(private),除非我们真的需要将其暴露,这样才能保证良好的封装性。
这通常应用于数据成员,但它同样适用于所有成员,包括虚函数。
C++ 类 & 对象
C++ 在 C 语言的基础上增加了面向对象编程,C++ 支持面向对象程序设计。类是 C++ 的核心特性,通常被称为用户定义的类型。
类用于指定对象的形式,是一种用户自定义的数据类型,它是一种封装了数据和函数的组合。类中的数据称为成员变量,函数称为成员函数。类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。
C++ 类定义
定义一个类需要使用关键字 class,然后指定类的名称,并类的主体是包含在一对花括号中,主体包含类的成员变量和成员函数。
定义一个类,本质上是定义一个数据类型的蓝图,它定义了类的对象包括了什么,以及可以在这个对象上执行哪些操作。
以下实例我们使用关键字 class 定义 Box 数据类型,包含了三个成员变量 length、breadth 和 height:
class Box
{public:double length; // 盒子的长度double breadth; // 盒子的宽度double height; // 盒子的高度
};
关键字 public 确定了类成员的访问属性。在类对象作用域内,公共成员在类的外部是可访问的。您也可以指定类的成员为 private 或 protected,这个我们稍后会进行讲解。
定义 C++ 对象
类提供了对象的蓝图,所以基本上,对象是根据类来创建的。声明类的对象,就像声明基本类型的变量一样。下面的语句声明了类 Box 的两个对象:
Box Box1; // 声明 Box1,类型为 Box Box Box2; // 声明 Box2,类型为 Box
对象 Box1 和 Box2 都有它们各自的数据成员。
访问数据成员
类的对象的公共数据成员可以使用直接成员访问运算符 . 来访问。
为了更好地理解这些概念,让我们尝试一下下面的实例:
#include <iostream>using namespace std;class Box
{public:double length; // 长度double breadth; // 宽度double height; // 高度// 成员函数声明double get(void);void set( double len, double bre, double hei );
};
// 成员函数定义
double Box::get(void)
{return length * breadth * height;
}void Box::set( double len, double bre, double hei)
{length = len;breadth = bre;height = hei;
}
int main( )
{Box Box1; // 声明 Box1,类型为 BoxBox Box2; // 声明 Box2,类型为 BoxBox Box3; // 声明 Box3,类型为 Boxdouble volume = 0.0; // 用于存储体积// box 1 详述Box1.height = 5.0; Box1.length = 6.0; Box1.breadth = 7.0;// box 2 详述Box2.height = 10.0;Box2.length = 12.0;Box2.breadth = 13.0;// box 1 的体积volume = Box1.height * Box1.length * Box1.breadth;cout << "Box1 的体积:" << volume <<endl;// box 2 的体积volume = Box2.height * Box2.length * Box2.breadth;cout << "Box2 的体积:" << volume <<endl;// box 3 详述Box3.set(16.0, 8.0, 12.0); volume = Box3.get(); cout << "Box3 的体积:" << volume <<endl;return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Box1 的体积:210 Box2 的体积:1560 Box3 的体积:1536
需要注意的是,私有的成员和受保护的成员不能使用直接成员访问运算符 (.) 来直接访问。我们将在后续的教程中学习如何访问私有成员和受保护的成员。
写在最后
发烧,难受,但是考虑到好久没发博客,所以就把上课的笔记拿出来了,睡觉去了,拜拜
相关文章:

C++数据封装以及定义结构的详细讲解鸭~
名字:阿玥的小东东 博客主页:阿玥的小东东的博客_CSDN博客-python&&c高级知识,过年必备,C/C知识讲解领域博主 目录 定义结构 访问结构成员 结构作为函数参数 指向结构的指针 typedef 关键字 C 数据封装 数据封装的实例 设计策略 C 类 &…...

MySql 数据库的锁机制和原理
MySQL是一种流行的关系型数据库管理系统,广泛应用于各种Web应用程序和企业级应用程序中。在MySQL中,锁是一种用于控制并发访问的机制,它可以保证数据的一致性和完整性。本文将介绍MySQL的锁机制及原理,包括锁的类型、级别和实现原…...

try catch finally 里面有return的执行顺序
目录 实例结论 实例 1.try和catch中有return时,finally里面的语句会被执行吗 我们可以来分别看看 (1)执行try中的return时 public class Solution {public static int show() {try {return 1;}finally{System.out.println("finally模块被执行");}}publi…...

美团前高级测试工程师教你如何使用web自动化测试
一、自动化测试基本介绍 1 自动化测试概述: 什么是自动化测试?一般说来所有能替代人工测试的方式都属于自动化测试,即通过工具和脚本来模拟人执行用例的过程。 2 自动化测试的作用 减少软件测试时间与成本改进软件质量 通过扩大测试覆盖率…...

MySql.Data.dll 因版本问题造成报错的处理
NetCore 链接MySQL 报 Character set ‘utf8mb3‘ is not supported by .Net Framework 异常解决_character set utf8mb3_csdn_aspnet的博客-CSDN博客 查看mysql版本号,两种办法: 第一种在数据库中执行查询:SELECT version; 第二种使用工具…...
囚徒困境——从博弈论的角度解释“美女配丑男”
前言 有一种很常见的现象,美女配丑男。其实这种现象背后是有一定科学原理的。本文将从博弈论的角度,从囚徒困境出发解释这一现象产生的原因。 囚徒困境 囚徒困境的经典案例 先来介绍一下经典的囚徒困境。 警方逮捕甲、乙两名嫌疑犯,但没有…...
运算符重载函数作为类的成员函数——有理数的约分
目录 一、题目 二、代码 三、算法分析 (一)数学表达式 (二) 代码实现 一)运算符重载函数 二)优化函数(实现有理数约分) 一、题目 通过运算符重载为类的成员函数来实现两个有…...
mysql数据库的内置函数--7
目录 内置函数 日期函数 字符串函数 数学函数 其它函数 内置函数 在mysql中这些函数用select进行使用 日期函数 函数描述NOW()返回当前的日期和时间CURDATE()返回当前的日期CURTIME()返回当前的时间DATE()从日期或日期/时间表达式中提取日期部分TIME()从日期或日期/时间…...

DS3800HPIB 有效执行任务的所有程序
DS3800HPIB是通用电气公司生产的Speedtronic Mark IV系列的一部分。这DS3800HPIB是一种大型电路板,具有八个连接端子,电路板两侧的尺寸各不相同。左下角有一个红色小方块,上面有一个拨动开关。这DS3800HPIB有大约50个天蓝色的小二极管。这DS3…...
图像比对、人像比对和人脸识别的区别是什么?
图像比对、人像比对和人脸识别都是图像处理技术,但是它们的实现方式和应用场景均有所不同。 图像比对 图像比对是指通过计算机视觉技术将两张或多张图片进行相似度比较。主要包括图像特征提取、匹配和评估等步骤,通常使用神经网络等深度学习技术来实现…...
python中的抽象基类
目录 协议和鸭子类型抽象基类定义抽象基类使用抽象基类直接继承通过注册(register) __subclasshook__魔法方法 协议和鸭子类型 python中有大量的魔法方法,python所谓基于协议编程,就是依赖这些魔法方法。 什么意思呢?…...

耗时几个月,终于决定把原本想用于商业的系统开源了
前言 嗨,大家好,我是希留,一个被迫致力于全栈开发的老菜鸟。 今天又来给小伙伴们分享一个基于 SpringBoot Vue 实现的前后端分离后台管理系统项目; 简介 这个项目是基于xiliu-tenant脚手架项目搭建而成,原本是帮朋…...

HarmonyOS应用端云一体化开发主要流程
图示 主要步骤 序号 阶段 任务 说明 1 创建端云一体化开发工程 选择工程类型与云开发模板 确定工程类型:选择“Application”或“Atomic Service”页签,确定创建的是HarmonyOS应用工程还是原子化服务工程。选择云开发模板,包括通用云开…...
NoSQL之 Redis配置与优化
NoSQL之 Redis配置与优化 ---------------------- 关系数据库与非关系型数据库 ---------------------------------------- ●关系型数据库: 关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一…...

Redis哨兵模式
1.哨兵模式是什么 解释一 哨兵巡查监控 master主机是否故障,如果故障了,根据投票数自动将一个从库转换为新数据库,继续对外服务。 解释二 监控redis 的运行状态,包括master和slave当master宕机后,能自动将slave切换…...

数据库管理-第七十六期 如何升级19c RAC(20230516)
数据库管理 2023-05-16 第七十六期 如何升级19c RAC1 回头处理2 升级AHF3 升级GI及DB3.1 拷贝所需文件3.2 升级OPatch3.3 升级GI与DB3.4 应用SQL变更 4 升级OJVM4.1 解压补丁4.2执行补丁冲突检查:4.3 升级OJVM4.4 应用SQL变更 5 最终验证总结 第七十六期 如何升级19…...

组合预测模型 | ARIMA-CNN-LSTM时间序列预测(Python)
组合预测模型 | ARIMA-CNN-LSTM时间序列预测(Python) 目录 组合预测模型 | ARIMA-CNN-LSTM时间序列预测(Python)预测结果基本介绍程序设计参考资料 预测结果 基本介绍 ARIMA-CNN-LSTM是一种结合了传统时间序列模型和深度学习模型的…...

实验四 面向对象分析与设计——UML类图与时序图
一、实验目的: 掌握面向对象分析中静态结构模型与动态行为模型的基本思想。学会识别系统中的类、类的属性和操作以及类之间的关系,掌握UML类图的绘制方法。了解时序图的作用和组成元素,掌握UML时序图的绘制方法。 二、实验仪器及实验环境&a…...

最短路径问题
如图,设定源点为D,终点为A,则D到A的最短路径是多少? 算法思路: 第一步,从源点D出发,此时能到达的选择是C和E,我们根据路径长度选择最少的作为下一个节点,于是选择C&…...

国内有哪些SAAS软件?SAAS软件有哪些优点?
国内有哪些SAAS软件?SAAS软件有哪些优点?不请自来答一下,通过SaaS软件与传统软件的对比来详细讲下SaaS软件有哪些优点? 配合以下内容食用更佳: 关于概念——深度详解什么是SaaS(软件即服务)关…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
OkHttp 中实现断点续传 demo
在 OkHttp 中实现断点续传主要通过以下步骤完成,核心是利用 HTTP 协议的 Range 请求头指定下载范围: 实现原理 Range 请求头:向服务器请求文件的特定字节范围(如 Range: bytes1024-) 本地文件记录:保存已…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...

C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
1.先用Visual Studio 2017打开Yichip YC31xx loader.vcxproj,再用Visual Studio 2022打开。再保侟就有.sln文件了。 易兆微芯片下载工具加开机动画下载 ExtraDownloadFile1Info.\logo.bin|0|0|10D2000|0 MFC应用兼容CMD 在BOOL CYichipYC31xxloaderDlg::OnIni…...
iOS性能调优实战:借助克魔(KeyMob)与常用工具深度洞察App瓶颈
在日常iOS开发过程中,性能问题往往是最令人头疼的一类Bug。尤其是在App上线前的压测阶段或是处理用户反馈的高发期,开发者往往需要面对卡顿、崩溃、能耗异常、日志混乱等一系列问题。这些问题表面上看似偶发,但背后往往隐藏着系统资源调度不当…...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)
漏洞概览 漏洞名称:Apache Flink REST API 任意文件读取漏洞CVE编号:CVE-2020-17519CVSS评分:7.5影响版本:Apache Flink 1.11.0、1.11.1、1.11.2修复版本:≥ 1.11.3 或 ≥ 1.12.0漏洞类型:路径遍历&#x…...

嵌入式学习笔记DAY33(网络编程——TCP)
一、网络架构 C/S (client/server 客户端/服务器):由客户端和服务器端两个部分组成。客户端通常是用户使用的应用程序,负责提供用户界面和交互逻辑 ,接收用户输入,向服务器发送请求,并展示服务…...

【MATLAB代码】基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),附源代码|订阅专栏后可直接查看
文章所述的代码实现了基于最大相关熵准则(MCC)的三维鲁棒卡尔曼滤波算法(MCC-KF),针对传感器观测数据中存在的脉冲型异常噪声问题,通过非线性加权机制提升滤波器的抗干扰能力。代码通过对比传统KF与MCC-KF在含异常值场景下的表现,验证了后者在状态估计鲁棒性方面的显著优…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

HubSpot推出与ChatGPT的深度集成引发兴奋与担忧
上周三,HubSpot宣布已构建与ChatGPT的深度集成,这一消息在HubSpot用户和营销技术观察者中引发了极大的兴奋,但同时也存在一些关于数据安全的担忧。 许多网络声音声称,这对SaaS应用程序和人工智能而言是一场范式转变。 但向任何技…...