C++:类和对象 I(访问限定符、this指针)

目录

类的定义

类的大小

访问限定符

实例化

this指针



 

类的定义

class就是类,class是C++中的一个关键字

当然类也可以是C语言中的struct,C++兼容struct,甚至还有一些升级

定义类的方式

class Date
{};

和C语言的struct一样,class是C++中定义类的一个关键字,Date是这个类的名字,我们需要在后面跟上一个 {}和;,{}里面可以放变量,函数等

定义在类里面的成员函数默认为inline

类的大小

class和struct的大小计算方式一致,和在C语言时的计算方法一致,以下博客有结构体的大小计算讲解

C语言:自定义类型:结构体-CSDN博客

明明C++的类和C语言不同,C语言只能放变量,C++不仅能放变量还能放函数,为什么还是按照C语言的方式只计算成员变量的方法来计算结构体的大小呢?

这是因为成员函数实际上并不存储在类的实例的内存空间中,它们存储在代码段内,而类的实例只存储成员变量

为什么存储在代码段?

因为在类外我们是需要定义多个该类的变量的,例如日期类:

#include<iostream>
using namespace std;class Date
{
public:// ...
private:int _year;int _month;int _day;
};int main()
{Date d1;Date d2;Date d3;// ...return 0;
}

每个日期类对象d1、d2、d3毋庸置疑一定要有它们专属的变量(_year、_month、_day),这才能让它们三个都有各自的日期

那为什么不要每一个日期类对象都有一个成员函数?因为浪费

我们只需要一个函数足以,这个函数就存储在代码段中,当它们需要这个函数时就去代码段中调用这个函数,将它们专有的成员变量传过去即可,那么怎么传呢?具体看下面this指针的讲解

访问限定符

这是跟C语言不同的地方,C语言没有访问限定符的概念,比较自由

是C++一种实现封装的方式,通过访问限定符选择性的将接口给外部的用户使用

有三种访问限定符:public、private、protected

具体使用方法如下: 

class Date
{
public:void Print(){cout << _year << "/" << _month << "/" << _day << endl;}private:int _year;int _month;int _day;
};

public的意思是公有的,公有的就代表可以被外部所访问,例如在main函数中可以使用

private的意思是私有的,私有的就代表不可以被外部所访问,一般都设置成员变量为私有的

protected是受保护的,它发挥作用的地方在继承的那部分,其他和private一致,不能被外部所访问

在继承中,protected外部不能访问,但是它的派生类(子类)可以访问到protected的内容,而private依旧不能访问

 class定义成员没有被访问限定符修饰时默认为private,struct则默认为public,这也是他们在C++中的区别

我们要怎么访问类里面呢?

class Date
{
public:void Print();private:int _year;int _month;int _day;
};void Date::Print()
{cout << _year << "/" << _month << "/" << _day << endl;
}int main()
{Date d1;d1.Print();return 0;
}

这是在类里面声明了Print()函数,在类外面定义了Print()函数

要注意的就是我们需要用::访问限定符访问Date里面,这样才能知道函数内部的_year、_month、_day是谁

访问函数只需要用 . 即可

实例化

class Date
{
public:void Print();// ...private:int _year;int _month;int _day;
};int main()
{Date d1;d1.Print();return 0;
}

在这个日期类中,private里的成员函数都只是声明,并不是定义,并没有开空间,所以他们不是实例化,他们就像一张图纸,只可以看不可以做

而下面的d1就是实例化出了一个日期类对象,可以使用它里面的成员函数

this指针

#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;Date d2;d1.Init(2024, 7, 12);d1.Print();return 0;
}

在上面的代码中,有了Date类的初始化函数Init,和打印函数Print,这样我们就可以给一个Date对象初始化和打印了

运行结果:

前面有说既然类里面的函数只存在代码区只需要一份共同调用即可,那我们使用d1对象调用的时候函数里面怎么拿到d1的成员变量?为什么不是d2?

这里其实C++隐含了一个this指针,是利用了this指针解决了这个问题

我们的函数其实可以写成这样

class Date
{
public:void Init(int year, int month, int day){this->_year = year;this->_month = month;this->_day = day;}void Print(){cout << this->_year << "/" << this->_month << "/" << this->_day << endl;}private:int _year;int _month;int _day;
};

照样可以运行成功,结果一样

其实函数主题和调用相当于这样

void Init(Date* const this, int year, int month, int day)
{this->_year = year;this->_month = month;this->_day = day;
}void Print(Date* const this)
{cout << this->_year << "/" << this->_month << "/" << this->_day << endl;
}int main()
{Date d1;d1.Init(&d1, 2024, 7, 12);d1.Print(&d1);return 0;
}

但实际上我们是不能这样自己显式的把this写在函数参数上的,编译器会报错

这些都是编译器帮我们做的是,编译器自动的把d1的地址传过去,自动用this指针访问了,所以我们不需要写

但是函数内部我们是可以使用这个this指针的,因为后续我们需要这个this指针,并不只是上面单纯的初始化、打印之类的


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

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

相关文章

企业国产操作系统选型适配实施方案

【摘要】企业在推动国产化进程时&#xff0c;需选择一款主流、稳定且安全的服务器操作系统作为其系统软件。在产品投入实际生产环境前&#xff0c;对上游软硬件的适配情况有深入了解至关重要。本文将重点介绍银河麒麟高级服务器操作系统V10&#xff08;以下简称麒麟V10&#xf…

昇思25天学习打卡营第14天|K近邻算法实现红酒聚类

红酒Wine数据集 类别(13类属性)&#xff1a;Alcohol&#xff0c;酒精&#xff1b;Malic acid&#xff0c;苹果酸 Ash&#xff0c;灰&#xff1b;Alcalinity of ash&#xff0c;灰的碱度&#xff1b; Magnesium&#xff0c;镁&#xff1b;Total phenols&#xff0c;总酚&#xf…

算法可以赋能教育业务的哪些场景?

本文内容就一个点&#xff0c;将算法应用到教育系统中的各场景&#xff0c;让每个业务模块都实现智能化 以下列举出所有的需求点 目录 一、千人千面&#xff0c;个性化推荐流&#xff0c;推荐用户感兴趣的内容 实现方案&#xff1a;CTR模型 应用场景&#xff1a;所有的内容…

Perl语言之数组

Perl数组可以存储多个标量&#xff0c;并且标量数据类型可以不同。   数组变量以开头。访问与定义格式如下&#xff1a; #! /usr/bin/perl arr("asdfasd",2,23.56,a); print "输出所有:arr\n"; print "arr[0]$arr[0]\n"; #输出指定下标 print…

NLP任务:情感分析、看图说话

我可不向其他博主那样拖泥带水&#xff0c;我有代码就直接贴在文章里&#xff0c;或者放到gitee供你们参考下载&#xff0c;虽然写的不咋滴&#xff0c;废话少说&#xff0c;上代码。 gitee码云地址&#xff1a; 卢东艺/pytorch_cv_nlp - 码云 - 开源中国 (gitee.com)https:/…

初始c语言 语句

一 认识语句 控制流语句 if-else语句&#xff1a;用于条件判断。for循环语句&#xff1a;用于循环执行一段代码。while循环语句&#xff1a;当条件为真时执行循环。do-while循环语句&#xff1a;先执行一次循环体&#xff0c;然后再判断条件。switch语句&#xff1a;根据不同的…

CEPH 硬盘读写慢问题影响

ceph使用时经常会碰到起不来的情况 第一种就是服务器负载高&#xff0c;这个基本都会觉察到 还有一种就是硬盘问题 硬盘写问题 初始化时ceph会自己进行填充操作 ceph-volume lvm zap /dev/sdx --destroy 我就碰到过没初始化问题 看着一切正常 但看写入速度才几百KB/s 正常都100…

ArrayList模拟实现

ArrayList模拟实现 ArrayList 的初步介绍常见操作 ArrayList 的简单模拟实现 ArrayList 的初步介绍 ArrayList也叫做顺序表&#xff0c;底层是一个数组。 在创建顺序表 时就应该规定 里面元素的数据类型&#xff0c;其中不能直接传基本数据类型&#xff0c;例如int、char。需要…

Java代码初始化块

目录 实例域代码块 静态域代码块 初始化代码块分为静态域代码块和实例域代码块&#xff0c;静态域代码块在类第一次被加载时被执行&#xff0c;实例域代码块在创建对象时被执行&#xff0c;一个类中可以有多个代码块。 实例域代码块 使用方法 可以有输出语句 可以对类的属…

vue实现a-model弹窗拖拽移动

通过自定义拖拽指令实现 实现效果 拖动顶部&#xff0c;可对整个弹窗实施拖拽&#xff08;如果需要拖动底部、中间内容实现拖拽&#xff0c;把下面的ant-modal-header对应改掉就行&#xff09; 代码实现 编写自定义指令 新建一个ts / js文件&#xff0c;用ts举例 import V…

基于modbus tcp通讯的雷赛导轨控制器调试软件

0.前言 之前工作遇到了雷赛电机驱动器设备&#xff0c;主要是用来控制光学导轨移动。雷赛的调试软件用的时串口通讯&#xff0c;还要他们定制的串口线&#xff0c;在现场都是485转网络的接口&#xff0c;调试起来也很不方便。所以我就照着他们的说明书&#xff0c;写了一个简易…

Vue3 引入Vanta.js使用

能搜到这篇文章 想必一定看过demo效果图了吧 示例 Vanta.js - Animated 3D Backgrounds For Your Website (vantajs.com) 1. 引入 在根目录 index.html中引入依赖 <script src"https://cdnjs.cloudflare.com/ajax/libs/three.js/r134/three.min.js"></sc…

基于SpringBoot+VueJS+微信小程序技术的图书森林共享小程序设计与实现:7000字论文+源代码参考

博主介绍&#xff1a;硕士研究生&#xff0c;专注于信息化技术领域开发与管理&#xff0c;会使用java、标准c/c等开发语言&#xff0c;以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年&#xff0c;拥有近12年的管理工作经验&#xff0c;拥有较丰富的技术架…

底软驱动 | U-boot移植点点滴滴

u-boot 移植要点 一般厂家直接提供 u-boot 源码&#xff0c;做查看、修改(增加新功能) 或 u-boot 版本升级这三大块的用处&#xff1b;后两种都需要对新板子做适配/移植。 如果没有提供 u-boot 源码&#xff0c;那么就从 u-boot 官方版本中找到一个最相近的板子配置进行移植&…

【QT】布局管理器

布局管理器 布局管理器1. 垂直布局2. 水平布局3. 网格布局4. 表单布局5. Spacer 布局管理器 之前使⽤ Qt 在界⾯上创建的控件, 都是通过 “绝对定位” 的⽅式来设定的&#xff1b;也就是每个控件所在的位置, 都需要计算坐标, 最终通过 setGeometry 或者 move ⽅式摆放过去。 …

排序-java(详解)

一&#xff0c;分类 主要的排序大致分为以下几类&#xff1a; 1&#xff0c;插入排序&#xff0c;又分为直接插入排序和希尔排序 2&#xff0c;选择排序&#xff0c;又分为选择排序和堆排序 3&#xff0c;交换排序&#xff0c;又分为冒泡排序和快速排序 4&#xff0c;归并…

【linux】服务器安装及卸载pycharm社区版教程

【linux】服务器安装及卸载pycharm社区版教程 【创作不易&#xff0c;求点赞关注收藏】 文章目录 【linux】服务器安装及卸载pycharm社区版教程1、到官网下载安装包2、通过终端wget下载安装包3、解压4、安装5、设置环境变量6、运行pycharm7、删除pycharm安装包、卸载pycharm …

从“卷模型”到“卷应用”:AI时代的价值重塑与个性化智能探索

&#x1f308;所属专栏&#xff1a;【其它】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您的点…

【漏洞复现】华测监测预警系统2.2 UserEdit.aspx SQL注入

声明&#xff1a;本文档或演示材料仅用于教育和教学目的。如果任何个人或组织利用本文档中的信息进行非法活动&#xff0c;将与本文档的作者或发布者无关。 一、漏洞描述 华测监测预警系统2.2&#xff08;HuaCe Monitoring and Early Warning System 2.2&#xff09;是一款由华…

人工智能算法工程师(中级)课程9-PyTorch神经网络之全连接神经网络实战与代码详解

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下人工智能算法工程师(中级)课程9-PyTorch神经网络之全连接神经网络实战与代码详解。本文将给大家展示全连接神经网络与代码详解&#xff0c;包括全连接模型的设计、数学原理介绍&#xff0c;并从手写数字识别到猫狗识…