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…

Spuer().__init__的意义

class MyModel(nn.Module):def __init__(self):super().__init__() # 调用 nn.Module 的 __init__# 现在 nn.Module 的初始化完成&#xff0c;我们可以添加自定义层self.conv1 nn.Conv2d(1, 20, 5)self.conv2 nn.Conv2d(20, 20, 5) super().__init__() 在这里确实是在显式调…

昇思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:/…

deepin 卸载nginx

在Deepin系统中&#xff0c;要卸载nginx&#xff0c;可以通过终端执行以下步骤&#xff1a; 停止nginx服务&#xff1a; sudo systemctl stop nginx 禁用nginx服务&#xff08;如果不再需要开机自启&#xff09;&#xff1a; sudo systemctl disable nginx使用包管理器卸载ngi…

初始c语言 语句

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

pyinstaller系列教程(一)-基础介绍

1.介绍 PyInstaller是一个用于将Python应用程序打包为独立可执行文件的工具&#xff0c;它支持跨平台操作&#xff0c;包括Windows、Linux和MacOS等操作系统。特点如下&#xff1a; 跨平台支持&#xff1a;PyInstaller可以在多个操作系统上运行&#xff0c;并生成相应平台的可…

Kotlin Flow 防抖 节流

防抖和节流是针对响应跟不上触发频率这类问题的两种解决方案。 一:防抖&#xff08;debounce&#xff09;的概念&#xff1a; 防抖是指当持续触发事件时&#xff0c;一定时间段内没有再触发事件&#xff0c;事件处理函数才会执行一次&#xff0c; 如果设定时间到来之前&#x…

CEPH 硬盘读写慢问题影响

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

Leetcode刷题4--- 寻找两个正序数组的中位数 Python

目录 题目及分析方法一&#xff1a;直接合并后排序方法二&#xff1a;二分查找法 题目及分析 &#xff08;力扣序号4&#xff1a;[寻找两个正序数组的中位数](https://leetcode.cn/problems/median-of-two-sorted-arrays/description/&#xff09; 给定两个大小分别为 m 和 n …

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;拥有较丰富的技术架…

详解 @MapperScan 注解和 @Mapper 注解

文章目录 1. Mapper 注解1.1 Mapper 注解的定义和用途1.2 Mapper 注解的使用示例 2. MapperScan 注解2.1 MapperScan 注解的定义和用途2.2 MapperScan 注解的使用示例 3. Mapper 注解与 MapperScan 注解的区别4. 使用 Mapper 和 MapperScan 的注意事项5. Mapper 和 MapperScan …

我会什么开发技能

java我会什么&#xff1f; 一、并发编程 1、并发编程&#xff1a;jdk中的courren包只能够类实现&#xff08;seamplore&#xff0c;CountDownLaunch&#xff0c;Pharse&#xff0c;CycliBarrier&#xff0c;CompletableFuture&#xff09;&#xff0c;AQS的原理&#xff0c;线…