C++【类和对象】(一)

文章目录

  • 前言
  • 1.类的定义
    • 1.1类定义格式
    • 1.2 访问限定符
    • 1.3 类域
  • 2. 实例化
    • 2.1 实例化的概念
    • 2.2 对象大小
  • 3.this指针
  • 结语

前言

在前文我们讲解了C++基础语法知识。本文将会讲解C++的类和对象。

1.类的定义

1.1类定义格式

class name
{}
  • class为定义类的关键字,name为类的名字,{}中为类的主体,注意{}后面的;不能省略。
  • 类主体中的内容也称为类的成员,类中的变量也被称为类的属性或者成员变量;类中的函数被称为类的方法或者成员函数。
  • 我们为了区分成员变量,一般会在成员变量上加一个特殊标记,例如在成员变量前面或后面加一个_或者my,但C++并不强制要求你要这样写,这只是一些惯例。
  • C++中struct也可以定义成类,C++兼容了C语言的用法,同时也把struct升级成了类,明显的变化就是struct也可以定义函数,但一般情况下我们还是使用class来定义类
  • 定义在类里面的函数默认是inline内联函数。
#include<iostream>
using namespace std;class cla
{int Func(int x, int y){return x + y;}int x;int y;
};struct str
{int Func(int x, int y){return x + y;}int x;int y;
};

接下来我们来使用一下类

#include<iostream>
using namespace std;class cla
{int Func(int x, int y){return x + y;}int x;int y;
};int main()
{cla c1;c1.x = 10;return 0;
}

在这里插入图片描述
这里我们可以看到发生了报错,那这是为什么呢?
接下来我们就需要了解访问限定符了。

1.2 访问限定符

  • C++的一种实现封装的方法,用类将对象的属性与方法结合到一起,让对象变得更方便,通过访问权限可以选择性的将接口提供给外部的用户使用。
  • C++一共有三个访问限定符,public(公用)、private(私有)、protected(保护);public修饰的成员在类外可被直接访问;private和protection修饰的成员则在类外被直接访问,private和protection目前的功能是一样的,直到继承才能体现出他们的区别。
    在这里插入图片描述
  • 访问权限也有自己的作用域,访问权限的作用域是从访问限定符出现的位置开始,直到下一个访问限定符出现位置,而过后续没有其他的访问限定符,则访问权限遇到 } 即类的结束。
    在这里插入图片描述
  • class定义时默认的访问限定符是private,而struct默认public。
struct str
{int Func(){return _x + _y;}int _x;int _y;
}; 
class cla
{int Func(){return _x + _y;}int _x;int _y;
};int main()
{cla c1;str s1;c1.Func();// error C2248: “cla::Func”: 无法访问 private 成员s1.Func();
}

1.3 类域

  • 类也定义了一个新的作用域,类的所以成员都在类的作用域中,在类外定义成员时,需要使用::作用域操作符来指明成员是属于哪个类域的。
#include<iostream>
using namespace std;class cla
{
public:void Func();private:int _x;int _y;
};void cla::Func()
{_x = 10;//函数主体……
}
int main()
{cla c1;c1.Func();
}

2. 实例化

2.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;}
private:
//这里只是声明,并没有开空间int _year;int _month;int _day;
};int main()
{
//Date类实例化出对象d1和d2Date d1;Date d2;d1.Init(2024, 9, 10);d2.Init(2024, 9, 20);d1.Print();d2.Print();return 0;
}

2.2 对象大小

我们简单回顾一下,我们之前学过C语言的结构体,结构体里面存有成员变量,结构体的成员变量要按照内存对齐的去进行计算大小,C++的类也是遵循这个规则。
但不同的是,C++支持类内拥有成员函数,那这些成员函数要不要参与计算呢,答案是不用的;首先函数被编译后是一段指令,对象是无法存储这些指令的,这些指令会存储在一个单独的区域(代码段),如果对象非要存储,那也只能存储成员函数的指针。
那我们再分析一下,对象中的成员函数指针有存储的必要吗?我们那Date类举例,Date实例化了d1和d2两个对象,他们都有自己独立的成员变量(_year, _month, _day),这些自然是要存储的,但是我们看看d1和d2的成员函数指针(通过反汇编来看)。
d1的init
Init的第一句代码的地址
在这里插入图片描述
d2的init

可以看到他们是一样的,这样存储在对象里面就太浪费了。假设我用Date实例化了100个对象,那么相同的成员函数指针就会被重复存储100次,这就太浪费了。
这⾥需要再额外哆嗦⼀下,其实函数指针是不需要存储的,函数指针是⼀个地址,调用函数被编译成汇编指令[call 地址]。

所以C++计算类的大小是只计算成员变量,计算时要遵循内存对齐的规则。
内存对齐的规则

  • 第一个成员在与结构体偏移量为0的地址处
  • 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处
  • 对齐数 = 编译器默认的一个对齐数 与 该成员变量的大小 进行比较得出的较小值
  • 类/结构体的总大小为:最大对齐数(成员变量中对齐数最大)的整数倍
  • 如果嵌套了结构体的情况,嵌套的结构体成员对齐到自己的成员中最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数(含嵌套结构体中成员的对齐数)的整数倍。
  • 细节可以看之前的博客:C语言自定义类型【结构体】中的结构体的内存对齐。
#include<iostream>
using namespace std;
class A
{void Func(){;}char c;int a;
};class B
{};class C
{void Func(){;}
};int main()
{A a;B b;C c;cout <<"class A:" << sizeof(a) << endl;cout <<"class B:" << sizeof(b) << endl;cout <<"class C:" << sizeof(c) << endl;return 0;
}

在这里插入图片描述
我们可以看到B、C类明明没有成员变量,可大小却是1,为什么明明没有成员变量还要给一个字节呢?因为如果一个字节都不给,你怎么表示这个类是存在的!所以这里给一个字节,纯粹是为了占位,表示对象是存在的。

3.this指针

我们拿Date类来举例,我们用同一个类模板实例化了两个不同的对象(d1和d2),但是我们调用的函数是同一个函数,而且我们也能看到这个函数把d1和d2给区分了,这是为什么呢?其实这里是C++给了个隐含的this指针,来解决区分的问题。

  1. 编译器编译后,类的成员函数会在形参的第一个位置,增加一个当前类类型的指针,叫做this指针。比如Date类的Init的真实原型为:void Init(Date * const this, int year, int month, int day)
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;
};
  1. 类的成员函数访问成员变量,本质还是通过this指针来访问的,例如Init函数给_year,显示的写就是this->_year = year;
#include<iostream>
using namespace std;
class Date
{
public:void Init(int year, int month, int day){_year = year;this->_month = month;this->_day = day;}void Print(){cout << _year << '/' << _month << '/' << _day << endl;}
private:int _year;int _month;int _day;
};
  1. C++规定,不能在实参和形参的位置显示的写this指针,但是可以在函数内显示的使用this指针

结语

本文初步讲解了c++的类和对象,讲解了类的定义、实例化、类的大小和this指针。

最后感谢您能阅读完此片文章,如果有任何建议或纠正欢迎在评论区留言,也可以前往我的主页看更多好文哦(点击此处跳转到主页)。
如果您认为这篇文章对您有所收获,点一个小小的赞就是我创作的巨大动力,谢谢!!!

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

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

相关文章

计算机网络传输层---课后综合题

线路&#xff1a;TCP报文下放到物理层传输。 TCP报文段中&#xff0c;“序号”长度为32bit&#xff0c;为了让序列号不会循环&#xff0c;则最多能传输2^32B的数据&#xff0c;则最多能传输&#xff1a;2^32/1500B个报文 结果&#xff1a; 吞吐率一个周期内传输的数据/周期时间…

网络协议全景:Linux环境下的TCP/IP、UDP

目录 1.UDP协议解析1.1.定义1.2.UDP报头1.3.特点1.4.缓冲区 2.TCP协议解析2.1.定义2.2.报头解析2.2.1.首部长度&#xff08;4位&#xff09;2.2.2.窗口大小2.2.3.确认应答机制2.2.4.6个标志位 2.3.超时重传机制2.4.三次握手四次挥手2.4.1.全/半连接队列2.4.2.listen2.4.3.TIME_…

加速开发体验:为 Android Studio 设置国内镜像源

Android Studio 是由 JetBrains 开发的一个官方 IDE&#xff0c;用于 Android 应用开发。由于网络原因&#xff0c;直接从 Google 的服务器下载可能会比较慢或者不稳定。幸运的是&#xff0c;我们可以通过配置国内镜像源来加速下载和更新。 文章目录 &#x1f4af; 修改 Gradle…

Python 从入门到实战23(属性property)

我们的目标是&#xff1a;通过这一套资料学习下来&#xff0c;通过熟练掌握python基础&#xff0c;然后结合经典实例、实践相结合&#xff0c;使我们完全掌握python&#xff0c;并做到独立完成项目开发的能力。 上篇文章我们讨论了类的定义、使用方法的相关知识。今天我们将学…

开源 AI 智能名片链动 2+1 模式 O2O 商城小程序在社群活动中的应用与时机选择

摘要&#xff1a;本文探讨了开源 AI 智能名片链动 21 模式 O2O 商城小程序在社群经济中的重要性&#xff0c;着重分析了如何借助该小程序适时举办大型活动以维持和引爆社群活跃度。通过对活动时机选择的研究&#xff0c;强调了针对社群用户量身定制活动时机的必要性&#xff0c…

GD32F103单片机-EXTI外部中断

GD32F103单片机-EXTI外部中断 一、EXTI及NVIC介绍二、编程实验2.1 相关库函数2.2 实验代码 一、EXTI及NVIC介绍 GD32和STM32的EXTI基本相似&#xff0c;具体见STM32F1单片机-外部中断GD32的EXTI包括20个相互独立的边沿检测电路请求产生中断或事件&#xff0c;4位优先级配置寄存…

C++中的new与delete

目录 1.简介 2.底层 1.简介 new是升级版的malloc&#xff0c;它会先开空间再去调用构造函数。 delete是升级版的free&#xff0c;它会先调用析构函数再free掉空间。 class A { public:A(int a10, int b10){a a1;b b1;}private:int a;int b; };int main() {//new会先开空间…

Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计

文章目录 Java代码审计篇 | ofcms系统审计思路讲解 - 篇4 | XXE漏洞审计0. 前言1. XXE代码审计【有1处】1.1. 搜索JRXmlLoader1.1.1. JRAntApiWriteTask1.1.2. JRAntUpdateTask1.1.3. TableReportContextXmlRule1.1.4. JasperCompileManager【存在漏洞】 1.2. 搜索XMLReader1.2…

并查集LRU cache

并查集的定义 将n个不同的元素划分成一些不相交的集合。开始时&#xff0c;每个元素自成一个单元素集合&#xff0c;然后按一定的规律将归于同一组元素的集合合并。在此过程中要反复用到查询某一个元素归属于那个集合的运算。适合于描述这类问题的抽象数据类型称为并查集(unio…

Qt (19)【Qt 线程安全 | 互斥锁QMutex QMutexLocker | 条件变量 | 信号量】

阅读导航 引言一、互斥锁1. QMutex&#xff08;1&#xff09;基本概念&#xff08;2&#xff09;使用示例基本需求⭕thread.h⭕thread.cpp⭕widget.h⭕widget.cpp 2. QMutexLocker&#xff08;1&#xff09;基本概念&#xff08;2&#xff09;使用示例 3. QReadWriteLocker、QR…

string类(C++)

哈喽各位&#xff01;&#xff0c;久违了&#xff0c;最近怎么样捏&#xff0c;本次进入C的string类&#xff0c;加油加油呀&#xff01; 随记&#xff1a;鼓励创新&#xff0c;宽容失败&#xff01; 1.标准库的string类 1.1string类的了解 string的文献参考链接-->strin…

Buck变换器闭环控制,simulink仿真模型(适合初学者学习)

Buck变换器&#xff0c;又称为降压斩波器&#xff0c;是一种常见的DC-DC转换器&#xff0c;广泛应用于电源管理领域。它通过开关元件&#xff08;通常是MOSFET或BJT&#xff09;的导通与截止&#xff0c;改变输入电压到负载的平均电压&#xff0c;从而实现电压的降低。在实际应…

828华为云征文——使用Flexus云服务器X实例CentOS镜像下创建MySQL服务器教程

一、概述 1.1 前言 当前正值华为云盛大的828 B2B企业庆典&#xff0c;其中Flexus X实例的特惠活动尤为吸引人眼球。对于追求极致算力表现&#xff0c;并期望在自建MySQL数据库、Redis缓存系统及Nginx服务器部署上获得卓越性能的企业用户而言&#xff0c;这无疑是一个不可多得的…

SpringCloud (1) 服务拆解

1 服务拆解和治理 1.1 服务拆解 微服务的核心就是服务拆分,将传统的大项目拆分为多个微型服务(服务或微服务),实现服务之间"高内聚(微服务职责单一),低耦合(微服务功能相对独立)"的目的 (1) 水平(横向)拆分:先搭出拆分框架,比如【公共服务】(比如:common服务,client…

Python数据分析与可视化(Python绘图详解)

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

轻量级流密码算法Trivium

轻量级流密码算法Trivium 0x0 Trivium算法简介 Trivium算法是由C&#xff0e;D Canniere和B&#xff0e;Preneel共同设计的一套对称加密算法&#xff0c;Trivium密码算法采用了分组密码和非线性反馈移位寄存器的设计思路。该密码算法总共288比特的内部状态&#xff0c;其中有…

数据篇| 关于Selenium反爬杂谈

友情提示:本章节只做相关技术讨论, 爬虫触犯法律责任与作者无关。 LLM虽然如火如荼进行着, 但是没有数据支撑, 都是纸上谈兵, 人工智能的三辆马车:算法-数据-算力,缺一不可。之前写过关于LLM微调文章《微调入门篇:大模型微调的理论学习》、《微调实操一: 增量预训练(Pretrai…

【手撕算法】快速排序(递归分治法)Python实现

一、算法 class Solution:def Partition(self, nums, low, high):pivotkey nums[low] # 元素copied, nums[low]空了出来while low < high:while low < high and nums[high] > pivotkey:high high - 1 # 直到找到一个nums[high]<pivotkey位置nums[low] nums[h…

Matlab simulink建模与仿真 第十七章(补充离散库和补充数学库)

参考视频&#xff1a;simulink1.1simulink简介_哔哩哔哩_bilibili 一、补充离散库和补充数学库中的模块概览 1、补充离散库 注&#xff1a;每个版本的补充离散库不一定相同&#xff0c;也不是每个版本的库都有如上所有模块。 2、补充数学库 二、离散直接传递函数Ⅱ模块 1、…

学生护眼台灯哪个品牌比较好?五款性价比高的学生护眼台灯

现在的孩子学习压力很大&#xff0c;在学校课程已经塞满了大半天&#xff0c;课后的作业更是不少&#xff0c;空闲时间还需要去课后补习班的数不胜数。用眼的次数非常的高&#xff0c;眼睛很容易感到疲惫&#xff0c;这时候我们一个宝贝大有作用&#xff0c;就是我们的护眼台灯…