【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.hqwc.cn/news/512227.html

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

相关文章

React报错 之 Objects are not valid as a React child

原文链接&#xff1a; 1、React报错之Objects are not valid as a React child 2、Objects are not valid as a React child error [Solved] 作者&#xff1a;Borislav Hadzhiev 以下文中涉及到的链接均来自于该作者&#xff0c;他写了很多相关的文章&#xff0c;可以多看看他的…

【MySQL】事务、锁

目录 事务案例场景模拟实现转账&#xff1a;从张三的账户转账500元到李四的账户SQL示例异常 什么是事务事务的特性&#xff0c;简称ACID 属性实现原理redo logundo log MySQL 中一条 SQL 更新语句的执行过程( InnoDB 存储引擎)事务的提交流程隔离性并发事务产生的问题事务隔离级…

MySQL基础-----SQL语句之DQL数据查询语句(上篇)

目录 前言 select基本语法 一、基础查询 1.查询多个字段 2.字段设置别名 3.去除重复记录 案例 二、条件查询 1.语法 2.条件 案例 三、聚合函数 1.聚合函数 2.语法 案例 前言 前面我们学习了DML和DDL语句&#xff0c;那么本期我们学习数据查询的语句&#xff08;DQ…

并查集(数据结构)

并查集是一种数据结构&#xff0c;他的作用有两个&#xff1a; 1&#xff0c;合并&#xff1a;将两个子集合并成一个集合 2&#xff0c;查找&#xff1a;确定某个元素处在哪个集合 fa[x]存节点x的父节点 查找&#xff1a; 就是为了找到某个点的根节点&#xff0c;如果找到了…

LZO索引文件失效说明

在hive中创建lzo文件和索引时&#xff0c;进行查询时会出现问题.hive的默认输入格式是开启小文件合并的&#xff0c;会把索引也合并进来。所以要关闭hive小文件合并功能&#xff01;

每日一练 | 华为认证真题练习Day192

1、下面是路由器RTB的部分输出信息&#xff0c;关于输出信息描迷错误的是: A. 接口上动态加入的组播组个数是1。 B. 加入的组播组地址是225.1.1.2 C. DISPLAY IGMP GROUP命令用来查看IGMP组播组信息&#xff0c;包括通过成员报告动态加入的组播组和通过命令行静态加入的组播组…

Python里的全局变量、局部变量、类的self.*

问题 困惑&#xff0c;leetcode第538题&#xff0c;写成下面这种&#xff0c;不能得到正确的答案&#xff1a; class Solution_a:def traverse(self, root, cur_sum):# 思路&#xff1a;中序遍历可以打印出有序的数组&#xff0c;那么反一下&#xff0c;先右后中再左就可以打…

YOLOv8独家原创改进:特征融合涨点篇 | 广义高效层聚合网络(GELAN) | YOLOv9

💡💡💡本文独家改进:即结合用梯度路径规划(CSPNet)和(ELAN)设计了一种广义的高效层聚合网络(GELAN),高效结合YOLOv8,实现涨点。 将GELAN添加在backbone和head处,提供多个yaml改进方法 💡💡💡在多个私有数据集和公开数据集VisDrone2019、PASCAL VOC实现…

类变量【静态变量 static】

类变量【静态变量 static】 什么是类变量如何定义类变量如何访问类变量类变量使用注意事项和细节 什么是类变量 类变量&#xff0c;也叫静态属性/静态变量&#xff0c;是该类的所有对象共享的变量&#xff1b;   1&#xff09;任何一个该类的对象去访问它时&#xff0c;取到的…

DAY 11有效括号 删除字符串中的相邻重复项 逆波兰表达式

3.有效的括号 给定一个只包括 (&#xff0c;)&#xff0c;{&#xff0c;}&#xff0c;[&#xff0c;] 的字符串 s &#xff0c;判断字符串是否有效。 有效字符串需满足&#xff1a; 左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的…

eclipse搭建java web项目

准备条件 eclipsejdk1.8 &#xff08;配置jdk环境&#xff09;apache-tomcat-8.5.97&#xff08;记住安装位置&#xff09; 一 点击完成 开始创建javaweb项目 import java.io.IOException; import java.io.PrintWriter;import javax.servlet.ServletException; import javax.s…

CAD图纸归档平台、CAD图纸归档系统

CAD图纸归档平台是用于管理和存储CAD图纸的在线平台。这些平台提供了多种功能&#xff0c;包括图纸上传、下载、版本控制、共享、协作和搜索等。它们可以大大提高CAD图纸的管理效率和协作效率&#xff0c;减少纸质图纸的使用和存储成本&#xff0c;同时也方便用户随时随地访问和…