当前位置: 首页 > news >正文

类和对象(上) - c++

1.类的定义

1.1  类定义格式

  1.  class 是定义类的关键字 ,后跟类的名字,{}部分为类的主体,(注意:最后类定义结束时不要忘了 ; )。
  2.  类体中内容称为类的成员:类中的变量称为成员变量; 类中的函数称为成员函数。
  3. 在c++中,struct也可以定义类(c++兼容c语言),同时struct升级成类,在里面也可以定义函数,不过与class还是存在一些区别。
  4. 定义在类里面的函数默认为内联函数。

1.2 访问限定符

存在三种1.public 

                  2.private

                  3.protected

  1. C++一种实现封装的方式,用类将对象的属性与方法结合在一起,让对象更加完善,通过访问权限选择性的将其接口提供给外部使用。
  2. public修饰的成员在类外可以直接被访问protectedprivate修饰的成员在类外不能直接被访,protected和private类似,但也存在区别。
  3. 定义的成员类没有显示修饰时,class默认是private,struct默认为public。
  4. 一般成员变量都会限制为为private/protected,需要给外部使用的成员函数会放为public。

1.3 类域

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

2.实例化

2.1 概念:用类类型在物理内存中创建对象的过程,称为类实例化出对象。

  1. 我们可以想象成:我们定义了一个类类型,这个类相当于一个建筑模型,包括材料(成员变量)和过程方法(成员函数),建造师(我们)通过这个类建造出一个一个的房子(对象),就是实例化。
  2. 我们定义了一个类,但只是声明是一个模型,并没有分配空间,也不能存储数据,实例化成对象后才分配物理空间。

2.2 对象大小

首先,对象里面有些啥?1.成员变量 2.成员函数。成员变量必然需要分配空间存储,但是成员函数就不需要。对于函数,在编译后是一段指令,无法存在对象里,而是存在代码段。我们只能存函数的指针,但是对于成员函数而言,我们实例化出100个对象时,每个对象都有一样功能的函数,一样的指针重复存储100次,就太浪费了。其实函数指针是一个地址,由于成员函数是类的一部分,它们的地址在编译时就已经确定,并且对于所有该类的对象实例都是相同的。这意味着,虽然每个对象实例的内存位置不同,但它们调用同一成员函数时,调用的函数体是相同的。种设计方式有助于节省内存,因为不需要为每个对象实例复制成员函数。

所以讨论对象大小,我们只需要看成员变量,对于c++的类任然遵循结构体内存对齐原则我在之前的文章中讲过    点击链接结构体对齐  。


3. this指针

一个类中,当然不止会有一个对象,当存在多个对象时,在调用时,函数是如何知道该访问哪个对象呢?所以c++给了一个隐形的this指针。

编译器编译后,类的成员函数默认都会在形参第一个位置,增加一个当前类类型的指针,叫做this
指针。


4. 通过实例化和this指针的学习练习

4.1 题目

class A
{
public:void Print(){cout << this << endl;cout << "A::Print()" << endl;}
private:int _a;
};
int main()
{A* p = nullptr;p->Print();return 0;
}

此代码,A.正常运行  B.运行崩溃

来看,在主函数里用类A定义了一个空指针,然后对空指针p进行解引用,引用A的Print函数,先打印this指针,因为是空所以这里打印出来是000000~,然后打印字符串。

在我们之前的学习中,可以知道如果对一个空指针进行解引用,是未定义行为,会产生崩溃。

但是在此题中,并不会运行崩溃,而是正常运行,选 A 。

4.2 为什么呢?

在之前讲到,成员函数在编译后是一段指令,没有存在类对象里面,是通过this指针进行调用。在编译时通过函数名就确定了地址,不会在对象里面找,在底层并不会进行解引用。写出来是为了通过语法这一关,告知是在这个类里面的函数。

4.3 如果

就会运行崩溃。

因为p的地址传给this指针后,进入函数,通过this解引用得到_a 就是空指针解引用。

是一样的。


分享到这。

个人主页点这里~

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 【React】常见的 HOC 使用案例
  • Qt Designer,仿作一个ui界面的练习(一):界面的基本布局
  • Unity四元数线性插值Lerp
  • C++篇:入门(2)
  • 重磅更新||Pyside6|Pyqt实现处理GUI界面获取的数据时进度条同步更新
  • 第一个 Flask 项目
  • 第十二节、人物下蹲
  • 生产力工具|vscode for mac安装及过程留存
  • 探索哈希表:C++中的实现与操作详解【Map、Set、数据结构】
  • 【Python学习手册(第四版)】学习笔记13.1-while、for循环
  • C++的STL简介(一)
  • R语言统计分析——描述性统计
  • YUM软件包管理工具:更改YUM源、配置本地YUM仓库
  • 前端学习AI历程
  • 计算机基础(Windows 10+Office 2016)教程 —— 第8章 多媒体技术及应用
  • 【干货分享】SpringCloud微服务架构分布式组件如何共享session对象
  • 2017 年终总结 —— 在路上
  • Create React App 使用
  • ESLint简单操作
  • exports和module.exports
  • Idea+maven+scala构建包并在spark on yarn 运行
  • Java 9 被无情抛弃,Java 8 直接升级到 Java 10!!
  • JavaScript-Array类型
  • Mac转Windows的拯救指南
  • Nacos系列:Nacos的Java SDK使用
  • Objective-C 中关联引用的概念
  • PAT A1017 优先队列
  • PV统计优化设计
  • SSH 免密登录
  • ubuntu 下nginx安装 并支持https协议
  • 第13期 DApp 榜单 :来,吃我这波安利
  • 基于Mobx的多页面小程序的全局共享状态管理实践
  • 聊聊sentinel的DegradeSlot
  • 微服务入门【系列视频课程】
  • 验证码识别技术——15分钟带你突破各种复杂不定长验证码
  • 异步
  • 深度学习之轻量级神经网络在TWS蓝牙音频处理器上的部署
  • 如何在招聘中考核.NET架构师
  • ​​​【收录 Hello 算法】9.4 小结
  • ​埃文科技受邀出席2024 “数据要素×”生态大会​
  • ​数据结构之初始二叉树(3)
  • # 数据结构
  • (11)MSP430F5529 定时器B
  • (2024.6.23)最新版MAVEN的安装和配置教程(超详细)
  • (3)Dubbo启动时qos-server can not bind localhost22222错误解决
  • (C#)获取字符编码的类
  • (C语言)fgets与fputs函数详解
  • (day 12)JavaScript学习笔记(数组3)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第13章第6节 (嵌套的Finally代码块)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第14章泛型第2节(泛型类的类构造函数)
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (k8s)Kubernetes本地存储接入
  • (zz)子曾经曰过:先有司,赦小过,举贤才
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)spring boot公选课在线选课系统 毕业设计 142011