C++初阶——类与对象(上篇)

一、写在前面

        类与对象是C++不同于C语言的一个板块,内容很多,笔者把这部分分为三篇博客来讲解,希望能够帮助各位读者更容易地理解这些知识点。弄清楚这一部分之后,C++就算是成功入门了。

二、面向过程和面向对象

        C语言就是典型的面向过程语言,关注的是过程,分析问题的求解步骤,通过函数调用逐步解决问题。

        面向对象的编程,主要关注对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

        对象可以用来模拟世界上任何一个实体,比如一个人,一辆汽车或者一个银行账户。以人来做例子,世界上有很多人,虽然世界上没有两个人是完全相同的,但是所有人之间都有一写共同的属性,比如名字、性别、身高等。在编程的时候,将这些共性抽取出来,定义为一个模板。为这个模板定义一个名字——类,它定义了一组具有相同属性(成员变量)和方法(成员函数)的对象,描述对象的共同特征和行为。

三、类

3.1类的定义

        与C语言中存在的结构体不同,在类中,不仅可以定义变量,还可以定义函数。在C++中,使用class作为定义一个类的关键字。

class className
{class body;//由成员变量和成员函数组成。
};

        class作为定义类的关键字,className为类的名字,{}中为类的主体,注意类定义结束后存在一个不可省略的分号。 类体中的内容称为类的成员,类中的变量称为类的属性或者成员变量;类中函数被称为类的方法或者成员函数

3.2类函数的定义方式

  1. 成员函数的声明和定义全部放在类体中,需要注意的是,这种写法会导致编译器将成员函数当作内联函数处理
  2. 类声明放在.h文件中,成员函数定义放在.cpp文件中。注意:成员函数名前需要加类名::

一般情况下,在学习的过程中采用第一种方式即可,在以后的项目或者工作中应该用第二种定义方式。

        另外,还有一则定义成员变量的小Tips。

class Date
{
public:void Init(int day){day = day;}
private:int day;int month;int year;
};

        能分清谁是形参,谁是真正的成员变量吗?所以,为成员变量取名字的时候,应该给它加上一个前缀或者后缀,以便区分。比如:

class Date
{
public:void Init(int day){——day = day;}
private:int _day;int _month;int _year;
};

3.3类的访问限定符及封装

         面向对象有三大特性:封装、继承、多态。封装的核心概念是将数据(属性)和操作这些数据的方法(行为)捆绑在一起,并对外部隐藏对象的内部实现细节,只开放公共接口以供调用。封装本质上是一种管理,让用户更方便使用类。

        C++实现封装的方式是:用类将对象的属性和方法结合在一块,让对象更加完善,通过访问权限,选择性的将接口提供给外部的用户使用。访问限定符允许开发者隐藏类的内部实现细节。通过限制对类成员的访问,可以防止外部代码直接修改对象的内部状态,从而保护对象的完整性。

        C++有三种访问限定符:public(共有)、protected(保护)、private(私有)。对它们有如下说明:

  1. public:修饰的成员在类外可以直接被访问,公开的类也可以被任何其他类访问和实例化。
  2. private:私有的类成员只能在定义它们的类内部被访问,私有的类不能被外部类访问,它们通常用于实现类的内部逻辑。
  3. public:受保护的类成员可以被定义它们的类以及所有子类(继承该类的类)访问。
  4. 访问权限作用域为:从该访问运算符开始直到下一个访问限定符出现为止。
  5. 如果后面没有访问限定符,作用域就到类结束。
  6. class的默认访问权限为private,struct为public。

3.4类的作用域

        类定义是一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用作用域解析运算符::

#include<iostream>
using namespace std;class my_Class
{
private:int _age;int _sex;
public:void print();my_Class(){_age = _sex = 1;}
};void my_Class::print()//需要指定print属于my_Class这个类
{cout << _age << " " << _sex << endl;
}
int main()
{my_Class d;d.print();return 0;
}

3.5类的实例化 

        前面说到,类是一群某些属性和方法相同的对象的抽象,是一个模板,将这个模板特殊化,用它来创建对象的过程被称为类的实例化

  1. 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它。
  2. 一个类可以实例化出多个对象,实例化出的对象,占用实际的物理空间,存储类成员变量
class my_class
{int _a;int _b;
};int main()
{class d;d._a = 1;d._b = 1;return 0;
}

3.6类对象模型 

        一个类中,既有成员变量,又有成员函数,那么一个类的对象中包含了什么?怎么计算一个类的大小?

        实际上,计算机只保存成员变量,而成员函数存放在公共的代码段。所以一个类的大小,实际就是该类中的成员变量之和。当然,在类中也存在着内存对齐的问题。你还记得什么是内存对齐吗?

四、this指针

#include<iostream>
using namespace std;class my_Class
{
private:int _age;int _sex;
public:void print();void my_Class_Init(int age, int sex){_age = age;_sex = sex;}
};void my_Class::print()
{cout << _age << " " << _sex << endl;
}
int main()
{my_Class d1,d2;d1.my_Class_Init(1, 2);d2.my_Class_Init(2, 4);d1.print();d2.print();return 0;
}

          上面的代码中,笔者实例化了两个对象。函数体中,没有关于不同对象的区分,那如果两个不同的对象调用同一个函数,函数是怎么知道该设置d1对象还是d2对象呢?

        在这里,笔者想说的是,在计算机科学中是没有黑魔法的,计算机所有的东西都是人做出来的,别人能想到的,你也能想到,所有的东西,只是你现在不知道而已,只要你坚持下去,总有一天,你会把所有的细节都搞明白的。

        这个问题也是如此,计算机中没有什么是凭感觉的,C++的编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),函数体中所有成员变量都是通过该指针去访问的。只不过所有的操作对用户都是透明的。在编写代码的时候,这一步只能由编译器帮我们完成

        需要注意的是:

  1. this指针的类型:类类型*const,即成员函数中,不能给this指针赋值。
  2. 只能在函数内部使用。
  3. this指针本质上是成员函数的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针。
  4. this指针式成员函数第一个隐含的指针形参,一般情况由编译器自动传递,不需要用户传递。

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

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

相关文章

Java如何实现PDF转高质量图片

大家好&#xff0c;我是 V 哥。在Java中&#xff0c;将PDF文件转换为高质量的图片可以使用不同的库&#xff0c;其中最常用的库之一是 Apache PDFBox。通过该库&#xff0c;你可以读取PDF文件&#xff0c;并将每一页转换为图像文件。为了提高图像的质量&#xff0c;你可以指定分…

论文略读:OneChart: Purify the Chart Structural Extraction via One Auxiliary Token

2024 旷视的work 图表解析模型 1 背景 对于之前的视觉语言模型&#xff0c;论文认为其有两点不足需要改进&#xff1a; 需要充分训练一个真正会看 chart 的 vision encoder单纯对文本输出算交叉熵损失&#xff0c;并不是最优的&#xff08;如上图所示&#xff0c;当ground-tr…

STM32CubeMX学习(三) SPI+DMA通信

STM32CubeMX学习&#xff08;三&#xff09; SPIDMA通信 一、简介二、新建STM32CubeMX项目并使用外部时钟三、SPI3配置四、相关代码五、测试 一、简介 本文将基于STM32F103RCT芯片介绍如何在STM32CubeMXKEIL5开发环境下进行SPIDMA通信。 操作系统&#xff1a;WIN10 x64硬件电…

iOS静态库(.a)及资源文件的生成与使用详解(OC版本)

引言 iOS静态库&#xff08;.a&#xff09;及资源文件的生成与使用详解&#xff08;Swift版本&#xff09;_xcode 合并 .a文件-CSDN博客 在前面的博客中我们已经介绍了关于iOS静态库的生成步骤以及关于资源文件的处理&#xff0c;在本篇博客中我们将会以Objective-C为基础语言…

Python爬虫:在1688上“拍立淘”——按图索骥的奇妙之旅

想象一下&#xff0c;你是一名古代的侦探&#xff0c;手中握着一张神秘的藏宝图&#xff0c;在1688的茫茫商品海洋中寻找与之匹配的宝藏。今天&#xff0c;我们将一起化身为代码界的“拍立淘”专家&#xff0c;使用Python爬虫技术&#xff0c;通过API接口按图搜索商品。准备好你…

如何在小红书发布笔记时显示外地IP地址

小红书平台在发布笔记时显示IP地址可能是由于网络爬虫或者某些技术手段抓取数据时所导致的。为了保护用户隐私和安全&#xff0c;显示外地IP地址&#xff0c;可以尝试以下几种方法&#xff1a; 1.检查发布环境&#xff1a; 确保你是在一个安全、可信的网络环境下发布笔记&…

Linux中查询Redis中的key和value(没有可视化工具)

1.进入redis安装目录 进入redis安装目录,找到redis-cli(redis的客户端) 2.登录redis客户端 登录redis的客户端,格式:redis-cli -h [host] -p [port] -a [password],懂的都懂!!! ./redis-cli -h 192.168.8.101 -p 6380 -a xxxx登录成功后就这样子 3.查看redis中所有的key和…

Unity Editor 快速移动资源

Editor 快速移动资源 &#x1f354;使用场景&#x1f32d;功能 &#x1f354;使用场景 一般想要移动一个资源到另一个目录的办法是选中资源拖拽过去&#xff0c; 但在一个比较大的项目中你得一直拖啊拖直到找到那个目录 &#x1f92f;。 使用本插件就可以省去拖拽的步骤&#…

特斯联巨亏数十亿:毛利率剧烈波动下滑,高管动荡引发关注

《港湾商业观察》施子夫 近期&#xff0c;重庆特斯联智慧科技股份有限公司&#xff08;以下简称&#xff0c;特斯联&#xff09;递表港交所&#xff0c;联席保荐机构中信证券和海通国际。 此番闯关港交所&#xff0c;特斯联三年半巨亏超70亿元&#xff0c;公司何时能扭亏为盈…

javaweb----VS code

前端开发神器&#xff1a;VS Code → 速度快、体积小、插件多 VS Code 安装官网&#xff1a;https://code.visualstudio.com/download VS Code一些必备的插件安装&#xff1a; 1、Chinese (Simplified) 简体中文 2、Code Spell Checker 检查拼写 3、HTML CSS Support 4…

使用 Kafka 和 MinIO 实现人工智能数据工作流

MinIO Enterprise Object Store 是用于创建和执行复杂数据工作流的基础组件。此事件驱动功能的核心是使用 Kafka 的 MinIO 存储桶通知。MinIO Enterprise Object Store 为所有 HTTP 请求&#xff08;如 PUT、POST、COPY、DELETE、GET、HEAD 和 CompleteMultipartUpload&#xf…

Linux: network: hw csum failure

文章目录 简介openvswitchifb: fix packets checksummellanoxiommu=ptmellanox 2mellanox 3建议简介 这里总结一下几个checksum的问题,仅供参考。需要看所使用的系统是否已经有了相应的fix。也可能是一个新问题,如果是新问题,恭喜发现了新的宝藏。 openvswitch Fix setti…

【Python】数据容器详解:列表、元组、字典与集合的推导式与公共方法

目录 &#x1f354; 列表集合字典的推导式 1.1 什么是推导式 1.2 为什么需要推导式 1.3 列表推导式 1.4 列表推导式 if条件判断 1.5 for循环嵌套列表推导式 1.6 字典推导式 1.7 集合推导式 &#x1f354; 数据序列中的公共方法 2.1 什么是公共方法 2.2 常见公共方法…

【PythonWeb开发】Flask-RESTful视图类基础知识

flask_restful 是一个扩展库&#xff0c;它为 Flask 提供了快速构建 RESTful API 的功能。使用 flask_restful 可以简化 RESTful API 的开发过程&#xff0c;减少样板代码&#xff0c;并且提供了一些高级特性&#xff0c;如 HTTP 方法的映射、资源路由的定义等。 在flask_restf…

1 C++ 编译属性 __attribute__((X))

__attribute__是GNU对标准C的扩展&#xff0c;可以用来设置函数属性&#xff08;Function Attribute&#xff09;、变量属性&#xff08;Variable Attribute&#xff09;和类型属性&#xff08;Type Attribute&#xff09;。 __attribute__使用 1 __attribute__((used))函数…

uniapp 使用uni.getRecorderManager录音,wav格式采样率低于44100,音频播放不了问题解决

如题&#xff1a;uniapp开发app端&#xff0c;使用uni.getRecorderManager录wav格式音频&#xff0c;采样率8000/16000都无法播放&#xff0c;44100可以播放。但由于项目需求需要录制采样率为8000的音频&#xff0c;于是引用了如下插件 插件地址(具体可以参考该插件的使用说明…

笔记:mysql升级 5.6至5.7

说明 一台已有数据的机器&#xff0c;停机升级&#xff0c;从MySQL Server5.6.48&#xff0c;升级到 5.7.38。 环境介绍 10.24.10.247&#xff0c;Mysql 5.6.48 CentOS Linux release 7.9.2009 (Core) 32G内存、500G数据盘/home&#xff1b; 实际数据量约120M&#xff0c;2个…

基于Unet卷积神经网络的脑肿瘤MRI分割

项目源码获取方式见文章末尾&#xff01; 回复暗号&#xff1a;13&#xff0c;免费获取600多个深度学习项目资料&#xff0c;快来加入社群一起学习吧。 《------往期经典推荐------》 项目名称 1.【YOLO模型实现农作物病虫害虫识别带GUI界面】 2.【卫星图像道路检测DeepLabV3P…

uni-app在H5页面唤起小程序登录 然后再回到当前页面

在H5页面触发小程序方法跳转到登录页面 wx.miniProgram.navigateTo({ url: /pages/login/index?webviewRedirect encodeURIComponent(redirectUrl) }); 携带对应的返回地址 在等于成功之后触发webViewPage 携带token if (this.webviewRedirect) { const tempUrl decodeU…

Unity XR Interaction Toolkit 开发教程(1):OpenXR 与 XRI 概述【3.0 以上版本】

文章目录 &#x1f4d5;Unity XR 开发架构&#x1f50d;底层插件&#xff08;对接硬件&#xff09;&#x1f50d;高层 SDK&#xff08;面向应用交互层&#xff09; &#x1f4d5;OpenXR&#x1f4d5;XR Interaction Toolkit&#x1f50d;特点&#x1f50d;XRI 能够实现的交互类…