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

c++类和对象新手保姆级上手教学(上)

前言:

  c++其实顾名思义就是c语言的升级版,很多刚学c++的同学第一感觉就是比c语言难学很多,其实没错,c++里的知识更加难以理解可以说杂且抽象,光是类和对象,看起来容易,但想完全吃透,真的挺难,所以我打算用三篇博客一起归纳介绍一下c++中关于类和对象的所有知识点。

面向过程?面向对象?

c语言是一门面向过程的语言,关注过程。

c++是一门面向对象的语言,关注对象。

那究竟什么是对象?什么是过程呢?

举个例子面向过程,我们洗衣服,一共有下面这些步骤:

 c语言就是关注过程,将这些过程一个一个用函数实现就能达到目的。

而c++注重对象比如送外卖,c++就关注商家 买家 骑手等对象,然后每个对象里面又要显示他们的状态,比如骑手就有休息中,派送中,取餐中等,如下图所示:

 类的定义:

  c++是兼容c语言的,所以在c++中完全可以像c一样使用struct,同时c++将struct升级成了类,我们在类里面可以定义函数,升级成类后又要兼容c,有点矛盾,所以加了一个新的关键字class,所以c++中一般用class来表示类,如下图定义一个日期类:

 所以不难看出c语言的struct和class一个重要区别就是class可以在里面定义函数,而且类的定义不必像struct一样加上类型,类名就是类型。

访问方法如下图:

 其实光这样是访问不了函数的,接下来就需要我们的域作用限定符了。

域作用限定符:

c++提出了3种访问限定符:

public修饰的成员可以在域外直接被访问。

protected和private在域外不能直接被访问。 

 至于protected和private的区别,在继承中会体现,这里没什么区别。

如果没有加访问限定符就是默认权限。

那么接下来又有一个struct和class的区别:

class中默认私有。

struct中默认公有。

访问权限作用域从该访问限定符出现到下一个访问限定符出现结束(或者类结束)

如下图设置访问限定符:

 在c++的惯例中成员变量都设置为私有,成员函数都设置为公有,因为惯例一般不要直接修改数据,修改数据都要函数去做,当然如果有某些函数你只希望在类里面使用,也可以弄成私有的。

 类的声明和定义分离:

  当一个类需要声明和定义分离时,不能按以前的方法,简单的声明定义分离,我们先来了解一下编译器的搜索原则:先局部域再全局域

类会形成一个新的域叫类域。

 所以编译器默认不会去类域里面查找,所以就可能会出现定义找不到的情况,正确的声明和定义分离如下图:

头文件:

.cpp定义文件:

 可以注意到此时需要在定义文件的函数名前面加上   域名::

这样编译器就会优先去该域里面查找。

计算类的大小:

  既然类中可以存放函数那么类的大小跟这些函数有关系吗?函数的地址存放在类里面吗?我们可以写一个小案例测试一下。

注意成员变量的存放还是跟结构体一样遵循内存对齐,不懂内存对齐的可以看我的上一篇文章。

通过上面的测试不难看出,计算类的大小时没有算Init函数的大小,说明成员函数的地址没有存放在类里面,那它存放在哪里呢?

类的成员函数地址统一存放在一个公共区域(代码段),避免空间浪费。

写个小案例证明一下上面的结论:

 我们把s1变成了空指针,但这里仍能进行正常运行,因为Print的地址在代码段,没在类里面,所以编译器没有对空指针的解引用,而是直接去代码段找到了函数的地址。

冷知识:

如果没有成员变量,只有成员函数又或者都没有的情况,类的大小是多少呢?

这两种的情况,类的大小都规定是1,因为如果一点空间都不给,就无法证明这个类存在过。

this指针:

所有成员函数都i有一个隐含的this指针,它是成员函数的第一个参数。

该指针指向该对象,也就是说改类里的所有成员都可以通过this指针访问。

举个简单的例子:

原本我们的类是这样的:

 但当编译器翻译过后就会先变成这样:

注意我们不能显示写this,不然会报错,和上图一样。

this指针被const了无法被修改,可以注意一下const的位置,补充一个小知识点:

const在*前  修饰指针指向的内容

const在*后  修饰指针本身

其实根据它的作用也可以判断出,可以用过this指针修改指向的内容,但不能修改指针本身。 

它在函数内部是可以使用的,如下图:

this指针特性总结:

1.在形参和实参的位置我们不能显示写(别跟编译器抢活)

2.它在函数内部可以使用 

3.const了,无法修改指针本身

4.因为它是所有成员函数的第一个参数,所有成员函数参数的个数永远都是n+1个

面试中this指针常考问题:

 1.this指针存在哪里?

在堆?栈?常量区?静态区?对象里面?

首先对象里面肯定排除,因为我们刚才计算类的大小的时候通过测试,并没有计算this指针的大小,所以排除对象里面。

再排除堆,因为只有malloc的空间才会在堆里面。

还可以排除静态区,因为只有static和全局变量才在静态区。

继续排除常量区,因为在c++中const的变量不在常量区

所以正确答案:栈  因为this指针是一个形参,而栈是用来存放  函数的返回地址、形参、局部变量、返回类型的。

2.下面代码的能正常运行吗?

正确答案是,程序奔溃,这里找到Print函数可以直接去代码段找,但执行该函数时,需要访问里面的_a,所以对s1进行了访问,而s1是空指针,这里出现了对空指针的解引用,所以程序奔溃。

类和对象上篇到此结束,中篇和下篇我会陆续发布,可以点我主页查看,宝藏博主,还不关注,干货满满,火速收藏!!!

 

相关文章:

  • The method toList() is undefined for the type Stream
  • 汇编的两道题
  • ES入门知识点总结
  • ChatGPT高效提问—prompt实践(智能辅导-心理咨询-职业规划)
  • 互联网加竞赛 基于计算机视觉的身份证识别系统
  • 前端工程化面试题 | 11.精选前端工程化高频面试题
  • Ubuntu忘记登录密码重置步骤
  • 使用 Spring Data JPA 和 Mybatis 结合的方式进行分页查询
  • 1414 - 期末考试成绩排名
  • 【分享】JLINK的SW调试模式连线方式
  • 【深度学习】S2 数学基础 P4 概率论
  • uniapp如何给视频组件设置图片
  • leetcode135. 分发糖果
  • 6、内网安全-横向移动WmiSmbCrackMapExecProxyChainsImpacket
  • C语言指针(初阶)
  • 【React系列】如何构建React应用程序
  • 【跃迁之路】【641天】程序员高效学习方法论探索系列(实验阶段398-2018.11.14)...
  • Apache Zeppelin在Apache Trafodion上的可视化
  • AWS实战 - 利用IAM对S3做访问控制
  • Facebook AccountKit 接入的坑点
  • HomeBrew常规使用教程
  • httpie使用详解
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • magento 货币换算
  • nodejs调试方法
  • PAT A1050
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • unity如何实现一个固定宽度的orthagraphic相机
  • web标准化(下)
  • 阿里云爬虫风险管理产品商业化,为云端流量保驾护航
  • 程序员最讨厌的9句话,你可有补充?
  • 机器学习学习笔记一
  • 记录:CentOS7.2配置LNMP环境记录
  • 目录与文件属性:编写ls
  • raise 与 raise ... from 的区别
  • 数据库巡检项
  • #git 撤消对文件的更改
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (react踩过的坑)Antd Select(设置了labelInValue)在FormItem中initialValue的问题
  • (安全基本功)磁盘MBR,分区表,活动分区,引导扇区。。。详解与区别
  • (转)fock函数详解
  • (转)母版页和相对路径
  • (转)平衡树
  • (转)树状数组
  • **Java有哪些悲观锁的实现_乐观锁、悲观锁、Redis分布式锁和Zookeeper分布式锁的实现以及流程原理...
  • .dwp和.webpart的区别
  • .net core 6 redis操作类
  • .net core Swagger 过滤部分Api
  • .net core 调用c dll_用C++生成一个简单的DLL文件VS2008
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .Net Web项目创建比较不错的参考文章
  • .Net6支持的操作系统版本(.net8已来,你还在用.netframework4.5吗)
  • .net项目IIS、VS 附加进程调试
  • .net与java建立WebService再互相调用
  • .so文件(linux系统)