【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. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

📝文章结语:

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

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

优思学院|拉丁方实验设计是什么?

今天&#xff0c;我要给大家带来一个六西格玛实验设计的小窍门——拉丁方设计。这是一种巧妙的方式&#xff0c;帮助我们探索不同因素&#xff08;输入&#xff09;对结果&#xff08;输出&#xff09;的影响&#xff0c;同时巧妙地处理那些我们不想要的“噪音因素”。 想象一…

GAMMA电源维修高压直流电源ES30P-5W ES系列

美国Gamma高压电源维修型号&#xff1a;D-ES30R-10N-5W/M&#xff0c;LXR30-1N&#xff0c;XRM5N-100W&#xff0c;ES50P-10W/DDPM&#xff0c;ES60P-10W/DDPM&#xff0c;RR20-20P/DDPM&#xff0c;ES30P-10W&#xff0c;ES60P-10W DDPM&#xff0c;RR60-18P/220V&#xff0c;…

Matlab偏微分方程拟合 | 完整源码 | 视频教程

专栏导读 作者简介&#xff1a;工学博士&#xff0c;高级工程师&#xff0c;专注于工业软件算法研究本文已收录于专栏&#xff1a;《复杂函数拟合案例分享》本专栏旨在提供 1.以案例的形式讲解各类复杂函数拟合的程序实现方法&#xff0c;并提供所有案例完整源码&#xff1b;2.…

springboot 加入 日志+ controller 加入全局异常捕获

提下比较好点 包含将捕获的异常堆栈完整的返回给前端。方便 后端人员用 swagger 或 knife 工具验证接口时&#xff0c;直接看到异常。 有啥用呢&#xff1f;在现场环境&#xff0c;或不方便远程服务器机器时&#xff0c;非常有用&#xff01;&#xff01;&#xff01; 同时&…

ChatGPT数据分析应用——漏斗分析

ChatGPT数据分析应用——漏斗分析 ​ 漏斗分析在数据分析中也比较常用&#xff0c;主要是用于发现各个转化流程中哪个环节有问题。接下来我们让ChatGPT解释这个方法的概念并提供相应的案例。发送如下内容给ChatGPT。 ​ ChatGPT收到上述内容后&#xff0c;返回如下结果。 漏斗…

分布式架构下 网络通信的底层实现原理(一)

什么是通信&#xff1f; 当我们通过浏览器访问一个网址时&#xff0c;一段时间后该网址会渲染出访问的内容&#xff0c;这个过程是怎么实现的呢&#xff1f; 这种通信方式是基于http协议实现的&#xff0c;那么什么是协议&#xff1f; 像一个中国人和一个外国人交流时&#xf…

Redis 配置文件详解

Units 单位 配置大小单位&#xff0c;开头定义了一些基本的度量单位&#xff0c;只支持bytes&#xff0c;不支持bit&#xff0c;大小写不敏感。 # Redis configuration file example. # # Note that in order to read the configuration file, Redis must be # started with …

无尘抹布在洁净室环境中的作用与重要性

导言&#xff1a; 洁净室环境&#xff0c;特别是在制药、电子和生物技术等行业中&#xff0c;对清洁和卫生的要求极为严格。无尘抹布在维护这些环境的洁净和卫生方面起着至关重要的作用。本文将探讨无尘抹布的重要性以及在洁净室环境中的各种应用。 了解无尘抹布 定义和组成&a…

TensorBoard——Pytorch版使用(附带案例演示)

TensorBoard是一个用于可视化机器学习实验结果的工具&#xff0c;可以帮助我们更好地理解和调试训练过程中的模型。 在PyTorch中&#xff0c;我们可以使用TensorBoardX库来与TensorBoard进行交互。TensorBoardX是一个PyTorch的扩展&#xff0c;它允许我们将PyTorch的训练中的关…

基于Vue的兴趣活动推荐APP的设计与实现

目 录 摘 要 I Abstract II 引 言 1 1 相关技术简介 3 1.1 框架 3 1.1.1 Spring MVC 3 1.1.2 Spring框架 3 1.1.3 MyBatis框架 3 1.1.4 VUE框架 3 1.2 开发语言 3 1.2.1 JAVA 3 1.2.2 JavaScript 4 1.3 设计模式 4 1.4 数据库 4 2 可行性分析 5 2.1 社会可行性 5 2.2 经济可行…

Extended Feature Pyramid Network for SmallObject Detection

摘要 各种尺度的特征耦合会削弱小对象的性能&#xff0c;本文中&#xff0c;我们提出了具有超高分辨率金字塔的扩展特征金字塔网络&#xff08;EFPN &#xff09;&#xff0c;专门用于小目标检测。具体来说&#xff0c;我们设计了一个新模块&#xff0c;称为特征纹理转移&#…

《Effective Modern C++》- 极精简版 5-14条

本文章属于专栏《业界Cpp进阶建议整理》 继续上篇《Effective Modern C》- 极精简版 1-4条。本文列出《Effective Modern C》的5-14条的个人理解的极精简版本。 Item5、优先考虑auto而非显示类型声明 auto的优势&#xff1a; 强制变量初始化在返回部分场景&#xff0c;会返回一…

释机器学习中的召回率、精确率、准确率

精确率和召回率又被叫做查准率和查全率&#xff0c;可以通过P-R图进行表示 如何理解P-R(精确率-召回率)曲线呢&#xff1f;或者说这些曲线是根据什么变化呢&#xff1f; 以逻辑回归举例&#xff0c;其输出值是0-1之间的数字。因此&#xff0c;如果我们想要判断用户的好坏&…

如何做好【沟通】管理

目录 管理的定义 管理的四大职能&#xff1a; 四共团队&#xff1a; 领导力&#xff1a; 沟通的四种类型听、说、读、写&#xff08;计划、报告&#xff09; 沟通四原则 思维框架&#xff1a;结构树报告 管理的定义 彼得.德鲁克&#xff1a;管理通过他人去完成任务的学…

基于java SSM图书管理系统简单版设计和实现

基于java SSM图书管理系统简单版设计和实现 博主介绍&#xff1a;多年java开发经验&#xff0c;专注Java开发、定制、远程、文档编写指导等,csdn特邀作者、专注于Java技术领域 作者主页 央顺技术团队 Java毕设项目精品实战案例《500套》 欢迎点赞 收藏 ⭐留言 文末获取源码联系…

c++ 11 新特性 不同数据类型之间转换函数之const_cast

一.不同数据类型之间转换函数const_cast介绍 const_cast是C11中引入的一种类型转换操作符&#xff0c;用于修改类型的const或volatile属性。const_cast的主要用途是移除对象的常量性&#xff0c;它是唯一具有此能力的C风格的转型操作符。在C11中&#xff0c;const_cast可以完成…

Linux安装,配置,启动HBase

Linux安装&#xff0c;配置&#xff0c;启动HBase 一、HBase安装&#xff0c;配置 1、下载HBase安装包 Hbase官方下载地址: http://archive.apache.org/dist/hbase 选择相应的版本点击下载&#xff0c;这里以2.3.5为例 # linux可以通过wget命令下载 wget https://archive…

如何解决Firefox提示“此网站可能不支持TLS1.2协议”的问题 错误代码:SSL_ERROR_UNSUPPORTED_VERSION

1.问题描述 当你在Firefox浏览器中访问一个网站时&#xff0c;可能会遇到这样的提示&#xff1a;   之后&#xff0c;不停地刷新或 重新输入&#xff0c;怎么也访问不进去&#xff1f;&#xff1f; 2.解决步骤 按照以下步骤操作&#xff0c;可以降低Firefox对TLS版本的要求…

HEUFT电源维修x-ray发生器维修HBE211226

HEUFT电源维修x-ray发生器维修HBE211253;海富HEUFT在线液位检测X射线发生器维修&#xff0c;不限型型号系列。 德国海富推出HEUFT在线液位检测装置,满瓶检测系统HEUFT有着强大的功能,它的模块机构能整合很多程序,并依据不同的产品及其包装特性,照相技术,高频技术或X-ray技术。…

[eslint error] ‘v-model‘ should be on a new line.

错误详情 错误原因 此问题是由于.eslintrc.js文件中的vue/max-attributes-per-line配置错误产生的 esline默认要求属性单独开一行 错误解决 所以解决的方法有两个一个是遵从eslint默认规则让属性新开一行,能解决问题 但是我不喜欢看这样子的代码,所以我只好去改掉eslint的规…