(学习总结10)C++类和对象1
C++类和对象1
- 一、类的定义
- 1.类定义格式
- 2.访问限定符
- 3. 类域
- 二、实例化
- 1.实例化概念
- 2.对象大小
- 三、this指针
- 四、C++和C语言实现Stack对比
以下代码环境在 VS2022。
一、类的定义
1.类定义格式
-
class 为定义类的关键字,Stack 为类的名字, { } 中为类的主体,注意类定义结束时后面分号不能省略。类体中内容称为类的成员,类中的变量称为类的属性或成员变量,类中的函数称为类的方法或者成员函数。
-
为了区分成员变量,一般习惯上成员变量会加一个特殊标识,如成员变量前面或者后面加 “ _ ” 或者 “ m ” 开头,注意C++中这个并不是强制的,只是一些惯例。
-
C++中 struct 也可以定义类,C++兼容C中 struct 的用法,同时 struct 升级成了类,明显的变化是 struct 中可以定义函数,一般情况下我们还是推荐用 class 定义类。
-
定义在类里面的成员函数默认加上 inline 。
#include <iostream>class Stack
{
public:// 成员函数void init(int n = 4){_arr = nullptr;_capacity = _size = 0;checkCapacity();}int top(){return _arr[_size - 1];}void pop(){--_size;}void push(int x){checkCapacity();_arr[_size++] = x;}void destroy(){free(_arr);_arr = nullptr;_capacity = _size = 0;}void checkCapacity(){if (_capacity <= _size){int newCapacity = _capacity == 0 ? 4 : _capacity * 2;int* temp = (int*)realloc(_arr, sizeof(int) * newCapacity);if (temp == nullptr){perror("realloc faild");return;}_arr = temp;_capacity = newCapacity;}}private:// 成员变量int* _arr;int _capacity;int _size;};int main()
{Stack st;st.init();st.push(1);st.push(2);st.push(3);st.destroy();return 0;
}
2.访问限定符
-
C++一种实现封装的方式,用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。
-
public 修饰的成员在类外可以直接被访问,protected 和 private 修饰的成员在类外不能直接被访问,protected 和 private 在这方面的作用是一样的。(在继承中才可体现他们的区别)
-
访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,如果后面没有访问限定符,作用域就到 “ } ” 即类结束。
-
class 定义成员没有被访问限定符修饰时默认为 private,struct 默认为 public。
-
一般成员变量都会被限制为 private / protected,需要给别人使用的成员函数会修饰为 public。
class Student
{// 访问限定符public:protected:private:};
3. 类域
- 类定义了一个新的作用域,类的所有成员都在类的作用域中,在类体外定义成员时,需要使用 “ :: ” 作用域操作符指明成员属于哪个类域。
- 类域影响的是编译的查找规则,下面程序中 init 如果不指定类域 Stack,那么编译器就把 init 当成全局函数,那么编译时,找不到 _arr 等成员的声明 / 定义在哪里,就会报错。指定类域 Stack,就是知道 init 是成员函数,当前域找不到的 _arr 等成员,就会到类域中去查找。
class Stack
{
public:void init(int x);private:int* _arr;int _capacity;int _size;};// 声明和定义分离
void Stack::init(int x)
{//...
}
二、实例化
1.实例化概念
- 用类类型在物理内存中创建对象的过程,称为类实例化出对象。
- 类是对象进行一种抽象描述,是一个模型一样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,用类实例化出对象时,才会分配空间。
- 一个类可以实例化出多个对象,实例化出的对象占用实际的物理空间,存储类成员变量。打个比方:类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,设计图规划了有多少个房间,房间大小功能等,但是并没有实体的建筑存在,也不能住人,用设计图修建出房子,房子才能住人。同样类就像设计图一样,不能存储数据,实例化出的对象才能分配物理内存存储数据。
2.对象大小
类实例化出的每个对象,都有独立的数据空间,所以对象中肯定包含成员变量。但成员函数不一样,首先函数被编译后是一段指令,对象中没办法存储,这些指令存储在一个单独的区域(代码段),那么对象中非要存储的话,只能是成员函数的指针。并且对象中也没有存储其指针的必要,Date 实例化 d1 和 d2 两个对象,d1 和 d2 都有各自独立的成员变量 _year / _month / _day 存储各自的数据,但是 d1 和 d2 的成员函数 init / print 指针却是一样的,存储在对象中就浪费了。如果用 Date 实例化 100 个对象,那么成员函数指针就重复存储 100 次,太浪费了。
#include <iostream>
using namespace std;class Date
{public:void init(int year = 2000, int month = 1, int day = 1){_year = year;_month = month;_day = day;}void print(){cout << _year << "/" << _month << "/" << _day << endl;;}private:// 只是声明,没有开空间int _year;int _month;int _day;};int main()
{Date d1;Date d2;d1.init(2024, 8, 2);d1.print();d2.init(2014, 8, 2);d2.print();return 0;
}
上面我们分析了对象中只存储成员变量,C++规定类实例化的对象也要符合内存对齐的规则。
内存对齐规则:
- 第一个成员在与结构体偏移量为 0 的地址处。
- 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
- 注意:对齐数 = 编译器默认的一个对齐数与该成员大小的较小值。
- VS中默认的对齐数为 8
- 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
- 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
博客 (学习总结6)C语言结构体的内存对齐和位段实现 对内存对齐有详细的解释,这里不赘述。
没有成员变量的类为表示对象存在,给定 1 字节,纯粹为了占位标识对象存在。
#include <iostream>
using namespace std;class Student
{;
};int main()
{Student a;// 大小都为 1 字节cout << sizeof(a) << endl;cout << sizeof(Student) << endl;return 0;
}
三、this指针
-
Date 类中有 init 与 print 两个成员函数,函数体中没有关于不同对象的区分,那当 d1 调用 init 和 print 函数时,为分辨应该访问的是 d1 对象还是 d2 对象,C++给了一个隐含的 this指针 解决这个问题。
-
编译器编译后,类的成员函数默认都会在形参第一个位置,增加一个当前类类型的指针,叫做 this指针。比如 Date 类的 init 的真实原型为,void init(Date* const this, int year, int month, int day)
-
类的成员函数中访问成员变量,本质都是通过 this指针 访问的,如 init 函数中给 _year 赋值,可改为 this->_year = year。
-
C++规定不能在实参和形参的位置显示的写 this 指针(编译时编译器会处理),但是可以在函数体内显示使用 this 指针。
-
this指针 存放在寄存器中。
class Date
{public://void init(Date* const this, int year = 2000, ...)void init(int year = 2000, int month = 1, int day = 1){// 不能修改//this = nullptr;//_year = year;//_month = month;//_day = day;this->_year = year;this->_month = month;this->_day = day;}void print(){cout << _year << "/" << _month << "/" << _day << endl;;}private:int _year;int _month;int _day;};
四、C++和C语言实现Stack对比
面向对象三大特性:封装、继承、多态,下面的对比可以初步体现封装。
通过下面两份代码对比,我们发现C++实现 Stack 形态上还是发生了挺多的变化,底层和逻辑上没啥变化。
C语言版本 Stack,详细可参考博客 栈的讲解与实现
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>#define INIT_CAPACITY 4#define EXPANSION_MULTIPLE 2typedef int STDataType;typedef struct Stack
{STDataType* arr;int size;int capacity;
} Stack, * pStack;bool StackEmpty(pStack pst)
{assert(pst);return pst->size == 0;
}void StackInit(pStack pst)
{assert(pst);pst->arr = NULL;pst->size = 0;pst->capacity = 0;
}void StackDestroy(pStack pst)
{assert(pst);free(pst->arr);pst->size = 0;pst->capacity = 0;
}void StackPush(pStack pst, STDataType x)
{assert(pst);if (pst->size == pst->capacity){int newCapacity = pst->capacity == 0 ? INIT_CAPACITY : pst->capacity * EXPANSION_MULTIPLE;STDataType* temp = (STDataType*)realloc(pst->arr, newCapacity * sizeof(STDataType));if (temp == NULL){perror("realloc failed");return;}pst->arr = temp;pst->capacity = newCapacity;}pst->arr[pst->size++] = x;
}void StackPop(pStack pst)
{assert(pst);assert(!StackEmpty(pst));--pst->size;
}STDataType StackTop(pStack pst)
{assert(pst);assert(!StackEmpty(pst));return pst->arr[pst->size - 1];
}int StackSize(pStack pst)
{assert(pst);return pst->size;
}
C++版本 Stack:
#include <iostream>
#include <assert.h>
using namespace std;const int INIT_CAPACITY = 4;const int EXPANSION_MULTIPLE = 2;typedef int STDataType;class Stack
{
public:bool empty();void init();void destroy();void push(STDataType x);void pop();STDataType top();int size();private:STDataType* _arr;int _size;int _capacity;};bool Stack::empty()
{return _size == 0;
}void Stack::init()
{_arr = nullptr;_size = _capacity = 0;
}void Stack::destroy()
{free(_arr);_arr = nullptr;_size = _capacity = 0;
}void Stack::push(STDataType x)
{if (_size == _capacity){int newCapacity = _capacity == 0 ? INIT_CAPACITY : _capacity * EXPANSION_MULTIPLE;STDataType* temp = (STDataType*)realloc(_arr, newCapacity * sizeof(STDataType));if (temp == nullptr){perror("realloc failed");return;}_arr = temp;_capacity = newCapacity;}_arr[_size++] = x;
}void Stack::pop()
{assert(!empty());--_size;
}STDataType Stack::top()
{assert(!empty());return _arr[_size - 1];
}int Stack::size()
{return _size;
}int main()
{Stack a;a.init();a.push(1);a.push(2);a.push(3);a.push(4);while (!a.empty()){cout << a.top() << endl;a.pop();}a.destroy();return 0;
}
- C++中数据都放到了类里面,通过访问限定符进行了限制,不能再随意通过对象直接修改数据,这是C++封装的一种体现,这个是最重要的变化。这里的封装的本质是一种更严格规范的管理,避免出现乱访问修改的问题。当然封装不仅仅是这样的,这里就不展开讲了。
- C++中有一些相对方便的语法,比如缺省参数,成员函数每次不需要传对象地址,因为 this 指针隐含的传递了,方便了很多,使用类型不再需要 typedef 类名就很方便。
相关文章:
(学习总结10)C++类和对象1
C类和对象1 一、类的定义1.类定义格式2.访问限定符3. 类域 二、实例化1.实例化概念2.对象大小 三、this指针四、C和C语言实现Stack对比 以下代码环境在 VS2022。 一、类的定义 1.类定义格式 class 为定义类的关键字,Stack 为类的名字, { } 中为类的主体…...
进击大数据系列(一):Hadoop 基本概念与生态介绍
进击大数据系列(一):Hadoop 基本概念与生态介绍-腾讯云开发者社区-腾讯云 Hadoop 简介-CSDN博客 hadoop-common-3.2.1.jar hadoop-mapreduce-client-core-3.2.1.jar hadoop-hdfs-3.2.1.jar hadoop-core 依赖之间关系...
评价类算法--模糊综合评价算法模型
一.概述 二.经典集合和模糊集合的基本概念 经常采用向量表示法来进行表示 三.隶属函数的三种确定方法 其中,梯形分布用得最多 四.应用:模糊综合评价 对应一个指定的评语: 选择一个方案:...
哪些系统需要按照等保2.0进行定级?
等保2.0适用的系统类型 根据等保2.0的要求,需要进行定级的系统主要包括但不限于以下几类: 基础信息网络:包括互联网、内部网络、虚拟专用网络等。云计算平台/系统:涵盖公有云、私有云、混合云等多种部署模式的云服务平台。大数据…...
自注意力和位置编码
一、自注意力 1、给定一个由词元组成的输入序列x1,…,xn, 其中任意xi∈R^d(1≤i≤n)。 该序列的自注意力输出为一个长度相同的序列 y1,…,yn,其中: 2、自注意力池化层将xi当作key,value,query来…...
“文件夹提示无法访问?高效数据恢复策略全解析“
一、现象解析:文件夹为何提示无法访问? 在日常使用电脑的过程中,不少用户可能会突然遇到文件夹提示“无法访问”的尴尬情况。这一提示不仅阻断了对重要文件的即时访问,还可能预示着数据丢失的风险。造成这一现象的原因多种多样&a…...
结构开发笔记(一):外壳IP防水等级与IP防水铝壳体初步选型
若该文为原创文章,转载请注明原文出处 本文章博客地址:https://hpzwl.blog.csdn.net/article/details/140928101 长沙红胖子Qt(长沙创微智科)博文大全:开发技术集合(包含Qt实用技术、树莓派、三维、OpenCV…...
WPF Datagrid控件,获取某一个单元格中的控件
在WPF应用程序中,比如需要获取特定 DataGrid 单元格中的 TextBlock 控件,可以通过访问 DataGridRow 和 DataGridCell 对象。以下是一个例子,展示如何获取 DataGrid 的第二行第一列中的 TextBlock 控件,并修改其属性。 1. 在XAML中…...
P10838 『FLA - I』庭中有奇树
前言 本题解较为基础,推导如何得出二分解题思路。 题目大意 给出无根带权树,双方采取最佳策略,求节点S->T的最短路。 有两种操作: 我方至多可以使用一次传送,花费k元从a传送到b(ab不能相邻…...
WebRTC简介
WebRTC简介 WebRTC(Web Real-Time Communication)是一项开源的实时通信技术,它允许网页浏览器进行实时语音、视频和数据共享通信,而无需安装额外的插件或应用程序。WebRTC的出现极大地简化了实时通信的开发和部署过程,…...
一套直播系统带商城源码 附搭建教程
本站没搭建测试过,有兴趣的自己折腾了,内含教程! 功能介绍: 礼物系统:普通礼物、豪华礼物、热门礼物、守护礼物、幸运礼物 提现方式:统一平台提现日期及方式,方便用户执行充值提现操作 连麦…...
Netty 总结与补充(十)
简单介绍一下 Netty?你为什么会用到Netty?说说你对Netty的认识?为什么选用Netty来做通信框架? Netty 是一个高性能、异步事件驱动的 NIO 框架,它提供了对 TCP、UDP 和文件传输的支持,作为一个异步 NIO 框架…...
循环实现异步变同步的问题
一、背景 在开发中遇到在循环中调用异步接口的问题,导致页面渲染完成时,没有展示接口返回后拼接的数组数据。二、问题 在代码中使用了map进行循环,导致调用接口的时候处于异步。this.form.list.map(async el>{el.fileList [];if(el.pic…...
测试GPT4o分析巴黎奥运会奖牌数据
使用GPT4o快速调用python代码,生成数据图表 测试GPT4o分析巴黎奥运会奖牌数据 测试GPT4o分析巴黎奥运会奖牌数据 1.首先我们让他给我们生成下当前奥运奖牌数 2.然后我们直接让GPT帮我们运行python代码,并生成奥运会奖牌图表 3.我们还可以让他帮我们…...
TF卡(SD NAND)参考设计和使用提示
目录 电路设计 Layout 设计说明 贴片注意事项 电路设计 1、参考电路: R1~R5 (10K-100 kΩ)是上拉电阻,当SD NAND处于高阻抗模式时,保护CMD和DAT线免受总线浮动。 即使主机使用SD NAND SD模式下的1位模式,主机也应通过上拉电…...
电源芯片负载调整率测试方法、原理以及自动化测试的优势-纳米软件
在芯片设计研发领域,负载调整率作为稳压电源芯片的关键性能指标,直接关系到芯片的稳定性和可靠性,因此其测试和优化显得尤为重要。以下是对负载调整率测试原理、方法以及使用ATECLOUD-IC芯片测试系统优势的进一步阐述: 负载调整率…...
C++威力强大的助手 --- const
Welcome to 9ilks Code World (๑•́ ₃ •̀๑) 个人主页: 9ilk (๑•́ ₃ •̀๑) 文章专栏: C之旅 const是个奇妙且非比寻常的东西,博主从《Effective C》一书中认识到关于const更深层次的理解,写此博客进行巩固。 &#x…...
测试环境搭建整套大数据系统(十八:ubuntu镜像源进行更新)
镜像源更新为清华源 报错显示 解决方案 做好备份 cp /etc/apt/sources.list /etc/apt/sources.list.bak查看配置信息 sudo vim /etc/apt/sources.listsudo sed -i s/cn.archive.ubuntu.com/mirrors.aliyun.com/g /etc/apt/sources.list sudo apt update...
第128天:内网安全-横向移动IPCATSC 命令Impacket 套件CS 插件全自动
环境部署 案例一: 域横向移动-IPC-命令版-at&schtasks 首先是通过外网web访问到win2008,获得了win2008的权限,这一步不做演示 因为里面的主机都不出网,所以只能利用win2008进行正向或者反向连接 信息收集 域内用户信息&…...
记录一次学习过程(msf、cs的使用、横向渗透等等)
目录 用python搭建一个简单的web服务器 代码解释 MSF msfvenom 功能 用途 查看payloads列表 msfconsole 功能 用途 msfvenom和msfconsole配合使用 来个例子 msf会话中用到的一些命令 在windows中net user用法 列出所有用户账户 显示单个用户账户信息 创建用户账…...
浅谈 React Hooks
React Hooks 是 React 16.8 引入的一组 API,用于在函数组件中使用 state 和其他 React 特性(例如生命周期方法、context 等)。Hooks 通过简洁的函数接口,解决了状态与 UI 的高度解耦,通过函数式编程范式实现更灵活 Rea…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
装饰模式(Decorator Pattern)重构java邮件发奖系统实战
前言 现在我们有个如下的需求,设计一个邮件发奖的小系统, 需求 1.数据验证 → 2. 敏感信息加密 → 3. 日志记录 → 4. 实际发送邮件 装饰器模式(Decorator Pattern)允许向一个现有的对象添加新的功能,同时又不改变其…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility
Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...
电脑插入多块移动硬盘后经常出现卡顿和蓝屏
当电脑在插入多块移动硬盘后频繁出现卡顿和蓝屏问题时,可能涉及硬件资源冲突、驱动兼容性、供电不足或系统设置等多方面原因。以下是逐步排查和解决方案: 1. 检查电源供电问题 问题原因:多块移动硬盘同时运行可能导致USB接口供电不足&#x…...
2.Vue编写一个app
1.src中重要的组成 1.1main.ts // 引入createApp用于创建应用 import { createApp } from "vue"; // 引用App根组件 import App from ./App.vue;createApp(App).mount(#app)1.2 App.vue 其中要写三种标签 <template> <!--html--> </template>…...
Python实现prophet 理论及参数优化
文章目录 Prophet理论及模型参数介绍Python代码完整实现prophet 添加外部数据进行模型优化 之前初步学习prophet的时候,写过一篇简单实现,后期随着对该模型的深入研究,本次记录涉及到prophet 的公式以及参数调优,从公式可以更直观…...
图表类系列各种样式PPT模版分享
图标图表系列PPT模版,柱状图PPT模版,线状图PPT模版,折线图PPT模版,饼状图PPT模版,雷达图PPT模版,树状图PPT模版 图表类系列各种样式PPT模版分享:图表系列PPT模板https://pan.quark.cn/s/20d40aa…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
