【C++】——类与对象引入和认识

                                                创作不易,多多支持!

前言

有了上一篇博客的基础以后,就正式进入C++类和对象的领域了,如果看完本篇文章对你有用,还请多多支持!!😘😘

一 面向过程和面向对象

1.面向过程

在之前用c语言的时候,我们写一个程序,通常需要把这个程序分成很多给步骤,所以c语言是一个关注过程,面向过程的语言。

很经典的例子就是我们洗衣服,得分为找到要洗的衣服,然后放进盆子里面,然后倒入洗衣液,再

之后放水,之后就是用手洗或者用洗衣机洗,洗完之后还需要晾衣服,假如是这样一个程序,那么

就是会分成很多个步骤逐个完成。

2.面向对象

C++是基于面向对象的,关注的是对象,它不太关注其中过程,只关心对象就行。

比如我们洗衣服就分为人,要洗的衣服,洗衣机,三个对象而已,我们不需要关注太多,那行繁琐

的步骤可能是在某个对象里面完成的,其他对象不需要关注它到底是怎么完成的

二  类的引入

 在C语言中我们学过结构体,C++的类就是对结构体的升级

因为在结构体中只能是定义变量,却不能定义函数,然而类是可以的

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
struct A
{void fun()//函数{cout << "类和对象" << endl;}int _year;int _momth;int _day;
};
int main()
{A a;a.fun();return 0;
}

如果是c语言则不能这样使用,但是对于C++来说,C++更喜欢用class来代替struct

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;
class A
{
public:void fun(){cout << "类与对象" << endl;}
private:int _year;int _momth;int _day;
};
int main()
{A a;a.fun();return 0;
}

如果用class去修饰,那么这个类的内容称为类的成员,里面的函数称为类的方法或成员函数,里面的变量称为类的成员变量

 三  类的定义

类的定义有两种方式

第一种就是上面那种,全部放在类体中,这种放在类里面的函数,编译器会把他们当作内联函数

第二种是把函数的定义放在外面,也就是把声明凡在.h文件,把定义放在.cpp,如果是这样定义的话,那么我需要在函数定义的地方加上域访问符

 第一张图是.h文件的,第二张图是.cpp文件的

四  类的访问限定符及封装

4.1  访问限定符

这里的访问限定符其实正上面就已经有了介绍,就是外面用类把对象的属性和方法封装起来,通过访问权限选择性去给用户使用

这里就是public,private,protected,三种

1. public 修饰的成员在类外可以直接被访问
2. protected private 修饰的成员在类外不能直接被访问 ( 此处 protected private 是类似的 )
3. 访问权限 作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
4. 如果后面没有访问限定符,作用域就到 } 即类结束。
5. class 的默认访问权限为 private struct public( 因为 struct 要兼容 C)

 其实上面第五点提到了class与struct的区别,其实不然,他们的区别还有在继承和模板的位置有,这里就不一一介绍,在后面再说

4.2  封装

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来
和对象进行交互
C++ 语言中实现封装,可以 通过类将数据以及操作数据的方法进行有机结合,通过访问权限来
隐藏对象内部实现细节,控制哪些方法可以在类外部直接被使用

 五  类的实例化

用类类型创建对象的过程,称为类的实例化

我们写的类其实是对对象的描述,也就是相当于打了一个草稿,或者画了一张图纸,并没有去把它变成一个物体也就是没用开辟空间给它,只有当我们把它实例化也就是创建对象的时候,它才会对分配空间存储成员变量

这里的空间并没有分配给里面的函数,因为函数是不存储再对象里面的,是存储在公共的代码区里面,这一点尤为重要

所以有了上面的认识,我们在计算类的大小的时候就不能把里面的函数大小算进来,只算里面的成员变量就行

对于空类来说,其大小为1个字节,这1个字节没有意义,只是说明它存在而已

  结构体内存对齐规则
1. 第一个成员在与结构体偏移量为 0 的地址处。
2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。
VS 中默认的对齐数为 8
3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。
这个规则同样适用与类

六  this指针

我先来看一段代码

class Date
{ 
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout <<_year<< "-" <<_month << "-"<< _day <<endl;}
private:int _year;     // 年int _month;    // 月int _day;      // 日
};
int main()
{Date d1, d2;d1.Init(2022,1,11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}

从代码中我们可以看出对象d1和d2都共用一个这个初始化函数,但是这个初始化函数是怎么分别出这两个对象不一样的呢?(类里面的函数都在代码区,只有成员变量算在类里面,占据类的内存) 

其实原本应该是这样的

class Date
{ 
public:void Init(Date*const this,int year, int month, int day)//这里就是把隐含的指针显示出来{this->_year = year;this->_month = month;this->_day = day;}void Print(){cout <<_year<< "-" <<_month << "-"<< _day <<endl;}
private:int _year;     // 年int _month;    // 月int _day;      // 日
};
int main()
{Date d1, d2;d1.Init(2022,1,11);d2.Init(2022, 1, 12);d1.Print();d2.Print();return 0;
}

所以说this指针的特性就是

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

所以我们一般不会像第二个那样去写,一般是采用第一个的形式去写,这样比较方便一点 

七 C语言和C++实现栈的比较 

现在我们用C去实现一个栈

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
typedef int DataType;
typedef struct Stack
{DataType* a;int size;int capacity;
}Stack;
void StackInit(Stack* ps)
{assert(ps);Stack* tmp;tmp = (DataType*)malloc(sizeof(DataType)*4);if (tmp == NULL){return 0;}else{ps->a = tmp;}ps->size = 0;ps->capacity = 4;
}
void StackDestroy(Stack* ps)
{assert(ps);free(ps->a);ps->a = NULL;ps->size = 0;ps->capacity = 0;
}
void CheckCapacity(Stack* ps)
{assert(ps);if (ps->capacity == ps->size){int newcapacity = ps->capacity * 2;DataType* tmp = (DataType*)realloc(ps->a, sizeof(DataType) * newcapacity);if (tmp == NULL){perror("realloc fail");return 0;}else{ps->a = tmp;ps->capacity = newcapacity;}}
}
void StackPush(Stack* ps,DataType x)
{assert(ps);CheckCapacity(ps);ps->a[ps->size++] = x;
}
bool StackEmpty(Stack* ps)
{assert(ps);return 0 == ps->size;
}
void StackPop(Stack* ps)
{if (StackEmpty(ps))return;ps->size--;
}
DataType StackTop(Stack* ps)
{assert(!StackEmpty(ps));return ps->array[ps->size - 1];
}
int StackSize(Stack* ps)
{assert(ps);return ps->size;
}

从里面可以看出来其实还是很麻烦的,注意这里我输入输出依然是c++的,因为c++兼容c,所以形式是c的,但是里面混了一点c++的东西

 那现在我们用C++ 去实现这个栈

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
typedef int DataType;
class Stack{
public:void StackInit(){Stack* tmp;tmp = (DataType*)malloc(sizeof(DataType) * 4);if (tmp == NULL){return 0;}else{_a = tmp;}_size = 0;_capacity = 0;}void StackDestroy(){free(_a);_a = NULL;_size = 0;_capacity = 0;}void StackPush(DataType x){CheckCapacity();_a[size++] = x;}bool StackEmpty(){return 0 == _size;}void StackPop(){if (StackEmpty())return;_size--;}DataType StackTop(){assert(!StackEmpty());return ps->array[_size - 1];}int StackSize(){return _size;}
private:void CheckCapacity(){if (_capacity == _size){int newcapacity = _capacity * 2;DataType* tmp = (DataType*)realloc(ps->a, sizeof(DataType) * newcapacity);if (tmp == NULL){perror("realloc fail");return 0;}else{_a = tmp;_capacity = newcapacity;}}}DataType* _a;int _size;int _capacity;
};

从两者的比较我们可以看出,如果我们用c++的方式去实现栈,那么就会减少大量的指针问题

C++中通过类可以将数据 以及 操作数据的方法进行完美结合,通过访问权限可以控制那些方法在
类外可以被调用,即封装 ,在使用时就像使用自己的成员一样,更符合人类对一件事物的认知。
而且每个方法不需要传递Stack*的参数了 ,编译器编译之后该参数会自动还原,即 C++ Stack *
参数是编译器维护的, C 语言中需用用户自己维护

这里的指针都被this指针所替代,不是说没有指针,只是这个this指针是看不见的隐含指针而已

所以指针不需要我们去维护,但是在C中需要自己去维护,这样就比较麻烦而且比较容易出错

希望看到这里,可以给一波关注加收藏!! 😁😁

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

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

相关文章

单链表实现通讯录

不过多赘述了 顺序表的增删查改-CSDN博客https://blog.csdn.net/bkmoo/article/details/137566495?spm1001.2014.3001.5502 使用顺序表实现通讯录-CSDN博客https://blog.csdn.net/bkmoo/article/details/137676561?spm1001.2014.3001.5502这里没有使用文件操作只是简单的使…

全程免费的ssl证书申请——七步实现网站https

全程免费的ssl证书申请步骤如下&#xff1a; 1 准备工作 首先确定好需要的证书类型&#xff0c;如单域名证书、通配符证书和多域名证书&#xff0c;准备好需要安装证书的域名。 2 选择CA 选择提供免费证书的服务商——JoySSL&#xff0c;并访问其官方网站&#xff0c;创建一…

3d软件哪个适合新手学?3D动画渲染怎么好

在不同的行业领域&#xff0c;3D建模和动画的需求各异&#xff0c;因此所需的3D软件工具也会有所不同。对于刚开始接触3D设计的新手来说&#xff0c;软件的易操作性、丰富的学习资源以及与自己专业领域相关的功能是选择时的重要考虑因素。以下是几款适合初学者入门的3D软件推荐…

【智能算法应用】灰狼算法(GWO)在低照度图像增强中的应用

目录 1.算法原理2.数学模型3.结果展示4.参考文献 1.算法原理 【智能算法】灰狼算法&#xff08;GWO&#xff09;原理及实现 2.数学模型 对于低照度图像的增强方式可以采用非线性变换函数来对图像的灰度值进行变化&#xff0c;对于不同环境下质量不同的图像&#xff0c;可以将…

YOLOv8+PyQt5输电线路缺陷检测(目前最全面的类别检测,可以从图像、视频和摄像头三种路径检测)

1.效果视频&#xff1a;YOLOv8PyQt5输电线路缺陷检测&#xff08;目前最全面的类别检测&#xff0c;可以从图像、视频和摄像头三种路径检测&#xff09;_哔哩哔哩_bilibili 资源包含可视化的输电线路缺陷检测系统&#xff0c;可识别图片和视频当中出现的五类常见的输电线路缺陷…

python:pyqt5案例(简易浏览器)

1、上接pyqt5基础https://blog.csdn.net/weixin_73011353/article/details/138051734https://blog.csdn.net/weixin_73011353/article/details/138051734 2、基本模块 # 定义一个名为BrowserWindow的类&#xff0c;继承自QMainWindow class BrowserWindow(QMainWindow):def _…

美国电子电器产品FCC认证讲解

美国FCC认证简介 FCC全称是Federal Communications Commission&#xff0c;中文为美国联邦通信委员会。于1934年由CommunicationACT建立&#xff0c;是美国政府的一个独立机构&#xff0c;直接对国会负责。FCC通过控制无线电广播、电视、电信、卫星和电缆来协调和国际的通信。涉…

Axure琐碎细节

文章目录 琐碎细节注释预览编写原型图的时候可以把颜色改为灰色标尺竖直文字左对齐Axure中的文字怎么添加元件层级问题如何找到各种各样的形状&#xff0c;比如三角形了 五角星了 十字架了给按钮设置简单的交互动作通过锁来等比例缩放 琐碎细节 注释 有时候我们需要给我们的元…

阿里云操作日记

昨天买了一个超级便宜的阿里云服务器&#xff0c;2核2G&#xff0c;3M固定带宽&#xff0c;40G ESSD Entry云盘&#xff0c;搭载一个简单的系统&#xff0c;就想到了docker轻量级&#xff0c;易于管理 其实docker很好用&#xff0c;第一步就是安装docker 一、docker安装与端口…

盲返模式:电商领域的新玩法与商业创新

大家好&#xff0c;我是微三云周丽&#xff0c;今天给大家分析当下市场比较火爆的商业模式&#xff01; 小编今天跟大伙们分享什么是什么是盲返模式&#xff1f; 随着互联网的深入发展&#xff0c;电商行业正面临着前所未有的机遇与挑战。在这个竞争激烈的市场环境中&#xff…

uniapp 使用地图

可以使用 map | uni-app官网 uniapp中的map标签&#xff0c;也可以自己引入地图的js 如下图 使用 uniapp中的map标签 需要注意要配置key

HTML 中创建 WebSocket服务与接收webSocket发送内容

效果图 服务端 html客户端接受的消息 接下来开始实现服务端 创建server.js const WebSocket require(ws);const wss new WebSocket.Server({ port: 8877 });wss.on(connection, function connection(ws) {console.log(WebSocket connection opened.);// 每隔 5 秒发送一次…

人耳的七个效应

1、掩蔽效应 • 人们在安静环境中能够分辨出轻微的声音&#xff0c;即人耳对这个声音的听域很低&#xff0c;但在嘈杂的环境中轻微的声音就会被淹没掉&#xff0c;这时将轻微的声音增强才能听到。 • 这种在聆听时&#xff0c;一个声音的听阈因另一声音的出现而提高的现象&…

2.搭建增长模型-福格行为模型

福格行为模型 Bmat B为行动 m是动机 a是能力 t是触发 mat三者是同时出现的 比如连续签到30天&#xff0c;才送1天会员&#xff0c;这明摆着欺负人&#xff0c;用户难有积极性 但是签到即可或者会员1天&#xff0c;连续30天送30天&#xff0c;这样用户每天都会积极的来签到&…

【数据结构】哈希桶

目录 前言&#xff1a; 开散列&#xff08;哈希桶&#xff09; 开散列的概念 哈希桶的模拟实现 整体框架 查找 插入 删除 析构函数 前言&#xff1a; 闭散列线性探测缺点&#xff1a;一旦发生哈希冲突&#xff0c;所有的产生哈希冲突的数据连续存储在一块区域&#xff…

ios微信小程序禁用下拉上拉

第一步&#xff1a; page.json配置页面的"navigationStyle":"custom"属性&#xff0c;禁止页面滑动 "navigationStyle":"custom" 第二步&#xff1a; 页面里面使用scroll-view包裹内容&#xff0c;内容可以内部滑动 <view class&…

Oracle中rman使用记录

最近在项目中&#xff0c;遇到使用RMAN的操作来恢复数据库中某个时间归档日志&#xff0c;RMAN的原理和理解&#xff0c;网友们百度了解一下。我重点将实操部分了。直接上实验环节&#xff0c;让网友更懂。&#xff08;特别提醒&#xff1a;我是1:1用VMware克隆数据库进行RMAN还…

如何看待AIGC技术

目录 1.概述 2.技术应用 2.1.媒体与内容创作 2.2.教育与学习 ​​​​​​​2.3.艺术创作 ​​​​​​​2.4.游戏产业 ​​​​​​​2.5.工业设计 ​​​​​​​2.6.对未来社会的影响 2.7.可能的发展方向 ​​​​​​​2.8.小结 3.伦理与风险 3.1.AIGC技术面临…

零基础HTML教程(26)--表单元素标注

文章目录 1. 引子2. 使用标注3. 元素的id与name4. 更好的写法5. 小结 1. 引子 我们看一个表单&#xff1a; <form>姓名&#xff1a;<input type"text"><br>手机号:<input type"text"><br>年龄:<input type"text&qu…

MES管理系统工单管理模块的重要性

在现代制造企业中&#xff0c;MES管理系统作为生产流程管理的核心&#xff0c;工单模块则扮演着不可或缺的角色。它不仅是MES管理系统的基石&#xff0c;更是连接各个生产环节的纽带&#xff0c;确保生产流程的顺畅与高效。 首先&#xff0c;我们需要明确MES管理系统在制造企业…