【C++干货基地】面向对象核心概念 | 访问限定符 | 类域 | 实例化 | 类对象模型


在这里插入图片描述

🎬 鸽芷咕:个人主页

 🔥 个人专栏: 《C++干货基地》《粉丝福利》

⛺️生活的理想,就是为了理想的生活!

引入

  哈喽各位铁汁们好啊,我是博主鸽芷咕《C++干货基地》是由我的襄阳家乡零食基地有感而发,不知道各位的城市有没有这种实惠又全面的零食基地呢?C++ 本身作为一门篇底层的一种语言,世面的免费课程大多都没有教明白。所以本篇专栏的内容全是干货让大家从底层了解C++,把更多的知识由抽象到简单通俗易懂。

⛳️ 推荐

前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站。

文章目录

  • 引入
  • ⛳️ 推荐
  • 一、面向对象的概念
    • 1.1 类的引入
    • 1.2 类的定义
      • 类的俩总定义方式
      • 类成员的名称规范
  • 二、类的访问限定符和封装
    • 2.1 访问限定符
    • 2.2 封装的概念
    • 2.3 类的作用域
  • 三、类的实例化
  • 四、类的对象模型
    • 4.1 类的大小如何计算?
        • 空类是如何计算的?
    • 4.2 类的储存方式?
    • 4.3 结构体内存对齐规则
  • 📝文章结语:

一、面向对象的概念

哈喽大家好啊,一眨眼我们就进入了C++ 最核心的部分了。C语言我们都知道是面向过程编程,而C++和C语言最大的不同就是面向对象编程了下面我们就来看一下面向对象编程和面向过程编程的不同把:

  • 面向过程

C语言都知道是面向过程,关注的是解决问题的过程比如说我们要洗衣服
在这里插入图片描述
在这里插入图片描述

需要关注这几个过程,而C++关注的是对象来解决问题

  • 面向对象
    在这里插入图片描述

C++的面向对象总共关注的是对象:洗衣服需要

  • 人、衣服、洗衣机、洗衣粉
    整个过程是人把衣服放到洗衣机里倒入洗衣粉然后启动就好了

并不需要我们去了解衣服究竟是如何洗的,以及如何甩干的?只需要关注对象去完成他就好了

1.1 类的引入

在C++总是兼容C语言的,以往我们结构体是只能定义结构而不能定义函数的,在C++中把结构体升级成了类结构体内不仅可以定义变量,也可以定义函数。

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;typedef int DataType;
struct Stack
{void Init(size_t capacity){_array = (DataType*)malloc(sizeof(DataType) * capacity);if (nullptr == _array){perror("malloc申请空间失败");return;}_capacity = capacity;_size = 0;}void Push(const DataType& data){// 扩容_array[_size] = data;++_size;}DataType Top(){return _array[_size - 1];}void Destroy(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}DataType* _array;size_t _capacity;size_t _size;
};
int main()
{Stack s;s.Init(10);s.Push(1);s.Push(2);s.Push(3);cout << s.Top() << endl;s.Destroy();return 0;
}

上面就是类引入的使用示范,以往我们函数都在结构体外面,现在结构体被升级为了类,也可以内部定义函数了。

  • 而且访问时只需要加 . 就可以访问结构体内部的成员函数了

1.2 类的定义

前面说了,结构体被升级为了类。这其实只是为了兼容C语言实际上再C++中我们更喜欢使用 class 来当做类的关键字。

🍸 语法演示:

class className
{
// 类体:由成员函数和成员变量组成
};  // 一定要注意后面的分号

🔥 class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。

类体中内容称为类的 成员 :类中的变量称为类的属性或 成员变量 ; 类中的函数称为类的方法或者 成员函数

类的俩总定义方式

关于类的时候我们一般都是在本文件内定义或者头文件 .h 分离定义类

  • 声明和定义都在类体
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << "/" << _month << "/" << _day << endl;}int _year;   int _month;int _day;
};
int main()
{Date A;A.Init(2023,03,23);A.Print();return 0;
}
  • 声明和定义分离
    • .h 文件
#pragma once
#include<iostream>
using namespace std;class Date
{
public:void Init(int year, int month, int day);void Print();int _year;int _month;int _day;
};
    • .c 文件
#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"void Date::Init(int year, int month, int day)
{_year = year;_month = month;_day = day;
}void Date::Print()
{cout << _year << "/" << _month << "/" << _day << endl;
}
    • main 文件
#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"int main()
{Date A;A.Init(2023,03,23);A.Print();return 0;
}

🔥 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。

类成员的名称规范

为什么我们要专门讲一下类成员的名称规范呢?因为如果我们命名不规范就会出现下面情况:

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;class Date
{
public:void Init(int year, int month, int day){year = year;month = month;day = day;}int year;   int month;int day;
};
int main()
{Date A;A.Init(2023,03,23);return 0;
}

这里你能看出来那个是成员变量那个是接收的值嘛?

在这里插入图片描述

  • 所以我们一般在成员变量前面加 _name,这样就可以有效区分成员变量了
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;class Date
{
public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}int _year;int _month;int _day;
};
int main()
{Date A;A.Init(2023,03,23);return 0;
}

二、类的访问限定符和封装

2.1 访问限定符

类为了更加安全还给我们提供了三种访问限定来用于使用控制权限:
在这里插入图片描述

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

注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

2.2 封装的概念

C++是一门面向对象语言,而java 、python 他们也是面向对象的语言,面向对象的语言一般都有最重要的三个特性性:封装、继承、多态。

  • 在类和对象阶段,主要是研究类的封装特性,那什么是封装呢?

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。

封装本质上是一种管理,让用户更方便使用类。比如说我们使用的电脑大家并不需要关心它是怎么组装的,只需要知道 电源 usb 鼠标 插在哪里去使用就可以了这其实就是封装的概念。

我们在定义一个类的时候成员变量就电脑里面的内容所以我们一般成员变量的访问权限一般都是私有的不允许外部直接访问成员变量

  • 而成员函数就相当于我们电脑上的接口,需要什么就直接调用就好了

2.3 类的作用域

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

class Person
{
public:void PrintPersonInfo();
private:char _name[20];char _gender[3];int  _age;
};
// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo()
{cout << _name << " " << _gender << " " << _age << endl;
}

三、类的实例化

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

类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;

比如说我们在类里面定义的成员变量,其实只是对他进行了声明,只有当我们去定义这个类的时候才会生成空间。

  • 其实就想我们以前定义结构体一样只有这个结构体真正定义出来才真正的生成空间了
int main()
{Person._age = 100;   // 编译失败:error C2059: 语法错误:“.”return 0;
}
  • 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
  • 类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图
    只有使用图纸建造除真正的方式才回真正的物理空间
    在这里插入图片描述

四、类的对象模型

4.1 类的大小如何计算?

一个类中既有类的成员变量,又有成员函数那么我们该如何计算类的大小呢?

  • 以往我们计算一个类的大小都是使用 sizeof 来计算现在就来继续试试吧!

在这里插入图片描述
诶这里我们就可以看到这里只是计算成员变量的大小并没有去计算成员函数的存储大小?

  • 其实这和我们类的储存方式有关系,仔细关注就会发现类的大小计算其实就是按照结构体的内存对齐规则来计算的
空类是如何计算的?
#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;class Date
{};
int main()
{Date A;cout << sizeof(A) << endl;return 0;
}

在这里插入图片描述

这里我们看到如果是空类的大小计算是1,这个是因为空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象。

  • 用来证明这个类是存在的

  • 大家自己去试试这个类该怎么计算呢?

#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
using namespace std;class Date
{void Print(){cout << "hello!" << endl;}
};
int main()
{Date A;cout << sizeof(A) << endl;return 0;
}

4.2 类的储存方式?

前面我的验证了,类的大小计算是按照结构体的内存对齐规则来存储的,那他的成员函数被储存在哪里了呢?

在这里插入图片描述
其实我们类里面的成员函数是,被存放在一个叫做代码区的地方了,和成员变量是单独存放的并且只有一份。

  • 也就是 对象可以定义很多个但是,成员函数只有一份。

为什么要这样去设计存储模型呢?你想如果我们每定义一个对象就生成一个函数指针来存放函数地址的话那么生成1000个对象那不就要去生成1000个函数指针这样不就照成空间的浪费了嘛?

把成员函数放到公共代码区的话就只需要调用就好了,完全不会照成空间的浪费

4.3 结构体内存对齐规则

结构体的内存对齐规程以前博主专门写过一篇博客详细介绍过大家感兴趣喜欢可以去看看

  • 结构体内存对齐规则
  • 1. 第一个成员在与结构体偏移量为0的地址处。
  • 2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

🔥 注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。VS中默认的对齐数为8

  • 3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
  • 4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

📝文章结语:

☁️ 看到这里了还不给博主扣个:
⛳️ 点赞🍹收藏 ⭐️ 关注
💛 💙 💜 ❤️ 💚💓 💗 💕 💞 💘 💖
拜托拜托这个真的很重要!
你们的点赞就是博主更新最大的动力!

在这里插入图片描述

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

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

相关文章

一分钟了解深度学习算法

自从20世纪40年代起人工智能&#xff08;AI&#xff09;问世以来&#xff0c;学者们不懈探索着如何使机器具备模拟人类学习能力的能力。随着计算性能的不断提升和算法的演进&#xff0c;深度学习算法已成为AI领域的核心技术。本文将简述深度学习算法的概念、构成要素、应用范围…

【亲测】注册Claude3教程,解决Claude3被封号无法发送手机验证码

【亲测】注册Claude3教程&#xff1a;解决无法发送手机验证码的问题 Anthropic 今日宣布推出其最新大型语言模型&#xff08;LLM&#xff09;系列——Claude 3&#xff0c;这一系列模型在各种认知任务上树立了新的性能标准。Claude 3 系列包括三个子模型&#xff1a;Claude 3 …

金三银四,程序员如何备战面试季

金三银四&#xff0c;程序员如何备战面试季 一个人简介二前言三面试技巧分享3.1 自我介绍 四技术问题回答4.1 团队协作经验展示 五职业规划建议5.1 短期目标5.2 中长期目标 六后记 一个人简介 &#x1f3d8;️&#x1f3d8;️个人主页&#xff1a;以山河作礼。 &#x1f396;️…

【单调栈】Leetcode 739.每日温度

【单调栈】Leetcode 739.每日温度 解法&#xff1a;维护单调栈栈中存的是数组的索引 解法&#xff1a;维护单调栈栈中存的是数组的索引 栈中存的是数组的索引 当新的值比当前栈顶的大&#xff0c;那么就执行出栈-更新result数组-判断当新的值比当前栈顶的大&#xff1f;的循环…

白银期货开户交割规则有哪些?

白银期货交割是指期货合约到期时&#xff0c;交易双方通过该期货合约所载商品所有权的转移&#xff0c;了结到期未平仓合约的过程。小编在此为大家详细介绍白银期货的交割规则有哪些。白银期货的交割规则有哪些&#xff1f;白银期货的交割规则主要有&#xff1a; 一、交割商品…

(3)(3.2) MAVLink2数据包签名(安全)

文章目录 前言 1 配置 2 使用 3 MAVLink协议说明 前言 ArduPilot 和任务计划器能够通过使用加密密钥添加数据包签名&#xff0c;为空中 MAVLink 传输增加安全性。这并不加密数据&#xff0c;只是控制自动驾驶仪是否响应 MAVLink 命令。 当自动驾驶仪处于激活状态时&#x…

【Python】进阶学习:pandas--info()用法详解

【Python】进阶学习&#xff1a;pandas–info()用法详解 &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订…

新零售SaaS架构:订单履约系统的概念模型设计

订单履约系统的概念模型 订单&#xff1a;客户提交购物请求后&#xff0c;生成的买卖合同&#xff0c;通常包含客户信息、下单日期、所购买的商品或服务明细、价格、数量、收货地址以及支付方式等详细信息。 子订单&#xff1a;为了更高效地进行履约&#xff0c;大订单可能会被…

科技创新赋能森歌制造-浅谈森歌高品质发展之路

随着时代的变迁&#xff0c;科技创新已成为推动制造业高质量发展的关键力量。森歌&#xff0c;作为厨电行业的佼佼者&#xff0c;始终坚守着对优质品质的承诺&#xff0c;并在品牌的科技化升级之路上不断迈进。 在制造业科技化的背景下&#xff0c;新型工业化、数字经济、制造…

TQTT X310 软件无线电设备的FLASH固件更新方法

TQTT X310 除了PCIE口全部兼容USRP 官方的X310&#xff0c;并配备两块UBX160射频子板以及GPSDO。TQTT X310可以直接使用官方的固件&#xff0c;但是不支持官方的固件升级命令。这篇BLOG提供烧写刷新FLASH的方法。 1&#xff0c;使用的是WINDOWS系统。首先给X310接入电源并开机…

vue3 中使用 TinyMCE 富文本编辑器

1. TinyMCE 官方网站地址&#xff08;可能需要魔法上网才能访问&#xff09; 我们直接找到 TinyMCE 关于 vue 的下载地址&#xff0c;其他框架的下载也在这里 2. 向下找&#xff0c;找到关于vue3下载的地方 下载命令 npm install --save "tinymce/tinymce-vue^5" 例…

Linux 模拟实现shell【简单实现】

shell的模拟实现 我们知道shell是一个永不退出的程序&#xff0c;所以他应该是一个死循环&#xff0c;并且shell为了防止影响到自己&#xff0c;我们在命令行上输入的所有命令都是由shell的子进程来执行的&#xff0c;所以它应该要有创建子进程的相关函数&#xff0c;当然也会…

loadrunner lr解决参数化一次取多条记录【一对多问题】

场景&#xff1a;批量进行工作汇报&#xff0c;一个项目下选择三个工作项进行汇报&#xff1b; 问题&#xff1a;项目GUID变化一次&#xff0c;工作项GUID要取三个值&#xff0c;也就是变化三次&#xff1b; 我们知道&#xff0c;在Parameter List中可以设置参数取值规则&…

Tomcat(二) 动静分离

一、(TomcatNginx)动静分离 1、单机反向代理 利用 nginx 反向代理实现全部转发至指定同一个虚拟主机 客户端curl www.a.com 访问nginx服务&#xff0c;nginx服务通过配置反向代理proxy_pass www.a.com:8080&#xff0c;最终客户端看到的是www.a.com 实验中&#xff1a;7-3 做客…

#QT(智能家居界面-界面切换)

1.IDE&#xff1a;QTCreator 2.实验 3.记录 &#xff08;1&#xff09;创建一个新界面&#xff08;UI界面&#xff09; &#xff08;2&#xff09;可以看到新加入一个ui文件&#xff0c;双击打开&#xff0c;设置窗口大小与登录界面一致 &#xff08;3&#xff09;加入几个PUS…

python 基础知识点(蓝桥杯python科目个人复习计划58)

今日复习内容&#xff1a;做题 例题1&#xff1a;仙境诅咒 问题描述&#xff1a; 在一片神秘的仙境中&#xff0c;有N位修仙者&#xff0c;他们各自在仙境中独立修炼&#xff0c;拥有他们独特的修炼之地和修炼之道&#xff0c;修炼者们彼此之间相互尊重&#xff0c;和平相处…

P-States/C-States/S-States/G-States/D-States

P-States是指处理器的性能状态&#xff0c;可以根据需要调整处理器的工作频率和电压来平衡性能和能效。 S-States是指系统的睡眠状态&#xff0c;可以让系统在空闲时进入低功耗状态以节省能量。 G-States是系统的全局状态&#xff0c;通常用于描述整个系统的运行状态。 C-St…

用ChatGPT计算植被归一化指数NDVI并出图的详细教程

用ChatGPT结合GIS计算植被归一化指数NDVI出图教程 用ENVI计算比较繁琐&#xff0c;如今AI的盛行&#xff0c;我们可以轻松解决计算问题&#xff0c;只需1一分钟变可以出图。 详细教学请看上方视频步骤。 更多ChatGPT教学内容请见&#xff1a;ChatGPT结合GIS&#xff1a;一分钟…

如何在Vue中进行单元测试?

前端开发中&#xff0c;单元测试是一个非常重要的环节&#xff0c;它可以帮助我们在开发过程中发现潜在的问题&#xff0c;并确保我们的代码在不断迭代的过程中依然能够保持稳定。在Vue中进行单元测试同样非常重要&#xff0c;本文将介绍如何在Vue项目中进行单元测试。 在Vue中…

Qt::TabWidget

在Tab的右上角添加控件 QPushButton *add new QPushButton; add->setText(""); add->resize(30,30); ui->tabWidget->setCornerWidget(add,Qt::TopRightCorner); 结果&#xff1a; Tab添加子页 QWidget*newp new QWidget; ui->tabWidget->add…