C++类和对象上

3e78cdbc5474468196586ac4cad9c377.png

1. 类的定义

1.1 类定义格式

• class为定义类的关键字,Stack为类的名字,{}中为类的主体,注意类定义结束时后⾯分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的⽅法或者成员函数。

语法:class{//成员,行为...};

• 为了区分成员变量,⼀般习惯上成员变量会加⼀个特殊标识,如成员变量前⾯或者后⾯加_ 或者 m开头,注意C++中这个并不是强制的,这个只是⼀些惯例。

• C++中struct也可以定义类,C++兼容C中struct的⽤法,同时struct升级成了类,struct用法和class一样(区别在访问限定符中),但⼀般情况下我们还是推荐⽤class定义类。

• 定义在类⾯的成员函数默认为inline(内联)。所以在实现复杂的程序中我们对于一些简单且调用多的函数我们直接在类里面定义,而复杂一些的函数则,在类里面声明,在对应的源文件里面定义。

eg:简单定义一个日期类

#include <iostream>
using namespace std;
class Date
{//行为void Prin(){;}
void Inin(int x,int y,int z)
{_day=x;_year=y;_month=z;
}//成员int _day;int _year;int _month;//....
};

定义完了之后又如何调用呢?而调用之前我们需要了解访问限定符。

1.2 访问限定符

3983392072b541a88947d1eae876235c.png

注:本文重点介绍public和private,protected以后再讲,就本文而言private,protected用法一致,没有区别。

• C++⼀种实现封装的⽅式,⽤类将对象的属性与⽅法结合在⼀块,让对象更加完善,通过访问权限选择性的将其接⼝提供给外部的用户⽤。

• public修饰的成员在类外可以直接被访问;protected和private修饰的成员在类外不能直接被访问,protected和private是⼀样的。

• 访问权限作⽤域从该访问限定符出现的位置开始直到下⼀个访问限定符出现时为⽌,如果后⾯没有访问限定符,作⽤域就到 }即类结束。

• class定义成员没有被访问限定符修饰时默认为private,struct默认为public。

• ⼀般成员变量都会被限制为private/protected,需要给别⼈使⽤的成员函数会放为public。

eg:上面日期类再完善

#include <iostream>
using namespace std;
class Date
{
public://行为void Prin(){	;}void Inin(int x,int y,int z)
{_day=x;_year=y;_month=z;
}
private://成员int _day;int _year;int _month;
};
int main()
{Date d1;return 0;
}

当不加private时可以访问到的对象

458bb8c776c443c0bea9edc48110f2b1.png

加private时可以访问到的对象

30b2df46b80646c8987ea11e362acff6.png

当我们有不希望别人修改或者不希望别人直接修改(只能通过我提供的路径修改),就⽤private。⼀般成员变量都会被限制为private/protected,需要给别⼈使⽤的成员函数会放为public。

1.3 类域

• 类定义了⼀个新的作⽤域,类的所有成员都在类的作⽤域中,在类体外定义成员时,需要使⽤ :: 作⽤域操作符指明成员属于哪个类域。

• 类域影响的是编译的查找规则,下⾯程序中Init如果不指定类域,那么编译器就把它当成全

局函数,那么编译时,找不到array等成员的声明/定义在哪⾥,就会报错。指定类域,就是知

道它是成员函数,当前域找不到的它时,就会到类域中去查找。

这个往往用在定义和声明分开的时候。

eg:上面日期类获取年函数在类里面声明,在类外面定义

class Date
{
public://行为void Prin(){	;}int Getyear();
private://成员int _day;int _year;int _month;
};int Date::Getyear()
{;
}

2类的实例化

2.1 实例化概念

• ⽤类类型在物理内存中创建对象的过程,称为类实例化出对象。

• 类是对象进⾏⼀种抽象描述,是⼀个模型⼀样的东西,限定了类有哪些成员变量,这些成员变量只是声明,没有分配空间,⽤类实例化出对象时,才会分配空间。

• ⼀个类可以实例化出多个对象,实例化出的对象 占⽤实际的物理空间,存储类成员变量。类就像是设计图,设计图规划了有多少个房间,房间⼤⼩功能等,但是并没有实体的建筑存在,也不能住⼈,⽤设计图修建出房⼦,房⼦才能住⼈。类就像设计图⼀样,不能存储数据,实例化出的对象分配物理内存存储数据。

实例化一般有两种方式,第一个是用类作类型,直接创建,此时用" . "来访问,第二个则是创建类指针,然后通过“ -> ”来访问,这两种都可以,我们习惯上用第一种,但一些考试种喜欢用第二种。

eg:

int main()
{Date d1;Date* d2;d1.Prin();d2->Prin();return 0;
}

2.2 对象⼤⼩

类实例化出的每个对象,都有独⽴的数据空间,所以对象中肯定包含成员变量,那么成员函数是否包含呢?⾸先函数被编译后是⼀段指令,对象中没办法存储,这些指令存储在⼀个单独的区域(代码段),那么对象中⾮要存储的话,只能是成员函数的指针。再分析⼀下,对象中是否有存储指针的必要呢,Date实例化d1和d2两个对象,d1和d2都有各⾃独⽴的成员变量_year/_month/_day存储各⾃的数据,但是d1和d2的成员函数Init/Print指针却是⼀样的,存储在对象中就浪费了。如果⽤Date实例化100个对象,那么成员函数指针就重复存储100次,太浪费了。其实函数指针是不需要存储的,函数指针是⼀个地址,调⽤函数被编译成汇编指令[call 地址], 其实编译器在编译链接时,就要找到函数的地址,不是在运⾏时找,只有动态多态是在运⾏时找,就需要存储函数地址。

9601afc719b944aca68d2cb8a579962d.png

对象的大小和C语言中的结构体规则差不多,遵循内存对齐。

采用内存对齐是因为操作系统采集数据时是按照一定的字节数采集的,如果不内存对齐有可能产生数据混杂,又需要分离数据,增加时间成本。故内存对齐本质上是拿空间换时间的做法

eg:

48a81c585ac84c388626cda40b0bba65.png

像这个,假如一次只能拿4个字节的话,就会导致int中有3个字节和char混杂了。

内存对⻬规则

• 第⼀个成员在与结构体偏移量为0的地址处。

• 其他成员变量要对⻬到某个数字(对⻬数)的整数倍的地址处。

• 注意:对⻬数 = 编译器默认的⼀个对⻬数 与 该成员⼤⼩的较⼩值。

• VS中默认的对⻬数为8

• 结构体总⼤⼩为:最⼤对⻬数(所有变量类型最⼤者与默认对⻬参数取最⼩)的整数倍。

• 如果嵌套了结构体的情况,嵌套的结构体对⻬到⾃⼰的最⼤对⻬数的整数倍处,结构体的整体⼤⼩就是所有最⼤对⻬数(含嵌套结构体的对⻬数)的整数倍

eg:

#include<iostream>
using namespace std;
// 计算⼀下A/B/C实例化的对象是多⼤?
class A
{public :void Print(){cout << _ch << endl;}
private:char _ch;int _i;
};
class B
{public :void Print(){//...}
};
class C
{};
int main()
{A a;B b;C c;cout << sizeof(a) << endl;cout << sizeof(b) << endl;cout << sizeof(c) << endl;return 0;
}

30eab25b169f4c0dabc6a25cce64d020.png

class A:char对齐数为VS对齐数8和本身大小1中的较小值1,即_ch只能从插入在对齐数倍数的行数开始插入,同理int对齐数为vs对齐数8和本身大小4中的较小值4,即_i只能从插入在对齐数倍数的行数开始插入例如,0 4 8 12... 将各变量顺序插入如上图所示,故A对象大小为8字节。

特别的当没有成员变量时,所以这⾥给1字节表⽰对象存在过,纯粹是为了占位标识对象存在,故BC对象大小都是1。

609307c6a67e4bb0be0723f4351d9f64.png

3. this指针

• Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调⽤Init和Print函数时,该函数是如何知道应该访问的是d1对象还是d2对象呢?那么这⾥就要看到C++给了⼀个隐含的this指针解决这⾥的问题

• 编译器编译后,类的成员函数默认都会在形参第⼀个位置,增加⼀个当前类类型的指针,叫做this指针。⽐如Date类的Init的真实原型为,

void Init(Date* const this, int x,int y, int z)

• 类的成员函数中访问成员变量,本质都是通过this指针访问的,如Init函数中给_year赋值,

e517906ca961487981c16e8d572fd638.png

• C++规定不能在实参和形参的位置显⽰的写this指针(编译时编译器会处理),但是可以在函数体内显⽰使⽤this指针。

this指针有什么作用呢,我们在下一篇中讲解。

4.日期类再完善

下面是通过本文章内容对日期类小应用。

#include <iostream>
using namespace std;
class Date
{
public://行为void Prin() {cout << _year <<' ' << _month <<' ' << _day << endl;}void Inin(int x, int y, int z){this->_day = z;this->_year = x;this->_month = y;}
private://成员int _day;int _year;int _month;
};
int main()
{Date d1;d1.Inin(2023, 11, 1);d1.Prin();return 0;
}

实例化对象调用方法

8c581654a80d4665875df40cdb45f4ea.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/58740.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

NineData云原生智能数据管理平台新功能发布|2024年10月版

10 月发布内容 本月发布 7 项更新&#xff0c;其中重点发布 2 项、功能优化 3 项、性能优化 1 项、其他发布 1 项。 重点发布​ 数据库 Devops - 数据生成​ NineData 支持在数据库中自动生成符合特定业务场景的随机数据&#xff0c;用于模拟实际生产环境中的数据情况&…

BGP路径属性与路由反射器

前言 IBGP水平分割规则用于防止AS内部产生环路&#xff0c;在很大程度上杜绝了IBGP路由产生环路的可能性&#xff0c;但是同时也带来了新的问题&#xff1a;BGP路由在AS内部只能传递一跳&#xff0c;如果建立IBGP对等体全互联模型又会加重设备的负担。 BGP 路径属性 AS_Path …

医学和生信web APP 平台- Appmatrix

医学&#xff08;和生信&#xff09;web APP 平台- Appmatrix 最近使用shinyproxy将平时所构建的shiny和streamlit医学类应用汇集在一起&#xff0c;实现一站式访问&#xff0c;另外&#xff0c;使用了自己电脑内网穿透&#xff0c;一定程度上缓解了数据分析类APP消耗计算资源…

Rust 力扣 - 1456. 定长子串中元音的最大数目

文章目录 题目描述题解思路题解代码题目链接 题目描述 题解思路 我们遍历长度为k的窗口&#xff0c;我们只需要记录窗口内的元音字母数量即可&#xff0c;遍历过程中刷新最大数目 题解代码 impl Solution {pub fn max_vowels(s: String, k: i32) -> i32 {let s s.as_byt…

Centos系统新增网卡后获取不到网卡的IP地址解决方法

一、问题描述 当我们给Centos系统添加了新的网卡后,使用查看IP地址命令【ip addr】时,发现新网卡没有获取到对应的IP地址信息,如下图所示: 二、解决方法 有两种解决方法:一种是自动获取IP地址;另外一种是手动配置IP地址; 2.1、自动获取IP地址 #自动获取网卡的IP地址命…

跨境卖家必备!好用的独立站建站工具推荐 !

对于跨境卖家来说&#xff0c;拥有一个独立站是拓展海外市场、提升品牌影响力的重要途径。而选择一款好用的独立站建站工具&#xff0c;则是成功搭建独立站的关键。 一、为什么跨境卖家需要独立站&#xff1f; 在跨境电商领域&#xff0c;独立站具有诸多优势。首先&#xff0c…

Windows Qt 6安装Oracle QOCI SQL Driver插件

本文参考 QOCI for the Oracle Call Interface (OCI)。 Windows 打开 Qt 6.8.0 (MSVC 2022 64-bit)。 Setting up environment for Qt usage… Remember to call vcvarsall.bat to complete environment setup! 执行 "D:\Program Files\Microsoft Visual Studio\2022\E…

书生实战营第四期-第二关python

一、任务1&#xff1a;完成Leetcode 383 1.代码 class Solution:def canConstruct(self,ransomNote: str, magazine: str) -> bool: # 创建一个字典来存储 magazine 中每个字符的出现次数 char_count {} # 遍历 magazine&#xff0c;统计每个字符的出现次数 for char…

计算机考研,选择西安交通大学还是哈工大?

C哥专业提供——计软考研院校选择分析专业课备考指南规划 经过全面分析&#xff0c;2025年考研西安交通大学和哈尔滨工业大学计算机专业的报考难度对比如下&#xff1a; 西安交通大学计算机专业 > 哈尔滨工业大学计算机专业 对于想要报考985高校计算机专业但核心目标是优…

CentOS系统查看CPU、内存、操作系统等信息

Linux系统提供了一系列命令可以用来查看系统硬件信息&#xff0c;如CPU的物理个数、核数、逻辑CPU数量、内存信息和操作系统版本。 查看物理CPU、核数和逻辑CPU 在多核、多线程的系统中&#xff0c;了解物理CPU个数、每个物理CPU的核数和逻辑CPU个数至关重要。超线程技术进一步…

项目升级到.Net8.0 Autofac引发诡异的问题

前两天把项目升级到.Net8.0了&#xff0c;把.Net框架升级了&#xff0c;其他一些第三方库升级了一部分&#xff0c;升级完以后项目跑不起来了&#xff0c;报如下错误&#xff1a; An unhandled exception occurred while processing the request. DependencyResolutionExcepti…

十八、【智能体】数据库:未来科技的大脑

在上一篇中我们讲到了 **变量 ** &#xff0c; 变量 的作用是保存用户个人信息&#xff0c;让 Bot记住用户的特征&#xff0c;使回复更加个性化。 上一篇内容为&#xff1a;https://blog.csdn.net/qq_40585384/article/details/143272599 但变量有一个缺点——存储的信息太单…

web文件包含include

php伪协议 在 PHP 中&#xff0c;伪协议&#xff08;Pseudo Protocols&#xff09; 也被称为 流包装器&#xff0c;这些伪协议以 php:// 开头&#xff0c;后面跟着一些参数&#xff0c;用于指定 要执行的操作 或 需要访问的资源。 伪协议表明这些协议并不是一个 真实的外部协议…

Diving into the STM32 HAL-----USART

如今&#xff0c;电子行业有许多串行通信协议和硬件接口可用。其中之一是通用同步/异步接收器/发射器接口&#xff0c;也简称为 USART。几乎每个微控制器都至少提供一个 UART 外设。几乎所有的 STM32 MCU 都提供至少两个 UART/USART 接口&#xff0c;但根据 MCU 封装支持的 I/O…

功能强大视频编辑软件 Movavi Video Editor Plus 2024 v24.2.0 中文特别版

Movavi Video Editor Plus中文修改版是一款功能强大的视频制作编辑软件&#xff0c;使用能够帮助用户快速从录制的素材中制作成一个精美的电影&#xff0c;支持进行视频剪辑&#xff0c;支持添加背影、音乐和各种音乐&#xff0c;软件使用简单&#xff0c;无需任何的经验和专业…

中国书画、

孙溟㠭浅析“古玺” “古玺”是秦以前印章的通称&#xff0c;远可追溯三代&#xff0c;兴盛于战国。古玺所用的文字是当时六国的篆书&#xff0c;也就是大篆&#xff0c;风格多种多样&#xff0c;变化不一&#xff0c;不容易认识。从文字形式上&#xff0c;可分阴文&#xff08…

WPF+MVVM案例实战(九)- 霓虹灯字效果控件封装实现

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、运行效果2、主菜单与界面实现1、主菜单2、霓虹灯字界面实现3、字体资源获取3、控件封装1.创建自定义控件2、依赖属性实现3、封装控件使用4、运行效果4、源代码获取1、运行效果 2、主菜单与界面实…

Python酷库之旅-第三方库Pandas(183)

目录 一、用法精讲 846、pandas.api.types.is_number函数 846-1、语法 846-2、参数 846-3、功能 846-4、返回值 846-5、说明 846-6、用法 846-6-1、数据准备 846-6-2、代码示例 846-6-3、结果输出 847、pandas.api.types.is_re函数 847-1、语法 847-2、参数 847…

【SSM详细教程】-13-SpringMVC详解

精品专题&#xff1a; 01.《C语言从不挂科到高绩点》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12753294.html?spm1001.2014.3001.5482 02. 《SpringBoot详细教程》课程详细笔记 https://blog.csdn.net/yueyehuguang/category_12789841.html?spm1001.20…

设计模式4-工厂模式策略模式

目录 一 工厂模式 1.1 思想 1.2 案例 1.2.1 接口 1.2.2 实现类 1.2.3 工厂类 1.2.4 调用 二 策略模式 2.1 思想 2.2 案例 2.2.1 接口 2.2.2 实现类 2.2.3 策略类 2.2.4 调用 三 工厂模式策略模式 3.1 思想 3.2 案例 3.2.1 接口 3.2.2 实现类 3.2.3 定义F…