【C++】- 类和对象(!!C++类基本概念!this指针详解)

news2024/11/18 3:33:58

类和对象

  • 引入类
  • 类的定义
  • 类的访问限定操作符
  • 类的作用域
  • 类的实例化
  • 类对象模型
  • this指针

引入类

在 C++中,引入了一个新的定义----------是一种用户自定义的数据类型,用于封装数据和行为。类可以看作是一个模板或蓝图,描述了一组相关的数据和对这些数据的操作方式。通过类,可以创建具体的对象来使用和操作这些数据。

类是C++面向对象编程的核心,为了便于理解,我们可以将类抽象成一架飞机:
在这里插入图片描述

学习了C语言之后,我们知道了结构体类型,但在C语言结构体内只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。在这里插入图片描述

我们在C++中,用struct实现链表,可以将我们的一系列函数放进去,而这些在C++中更喜欢用class来代替。

在这里插入图片描述

在 C++ 中,structclass 都可以用于定义自定义数据类型,它们的区别主要有以下两点:

  1. 默认访问权限不同:struct 的默认访问权限是公有的,而 class 的默认访问权限是私有的。这意味着在 struct 中定义的成员变量和成员函数是公有的,可以被外部访问;而在 class 中定义的成员变量和成员函数是私有的,只能在类内部访问。

  2. 继承方式不同:在没有显式指定继承方式时,class 的继承方式是私有继承(private),而 struct 的继承方式是公有继承(public)。即如果一个类没有指定继承方式,则其默认继承方式与其类型相同。

类的定义

类的基本定义形式是:

class className
{
    // 类体:由成员函数和成员变量组成
}; 

类体内的内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为成员函数

在这里插入图片描述
在这里插入图片描述这里注意!在类内直接定义的函数 会被默认视为内联函数,但并不意味着所有在类内定义的函数都是内联函数。

内联函数是一种编译器优化的机制,它将函数的定义体直接插入到调用该函数的地方,而不是通过函数调用的方式执行。这样可以减少函数调用的开销,提高程序的执行效率。
就像这样直接插入:
在这里插入图片描述

在这里插入图片描述在类内定义的函数,默认情况下会被视为内联函数。但是,如果函数体过于庞大复杂,编译器可能会忽略内联函数的请求,将其视为普通函数进行处理。因此,并不是所有在类内定义的函数都会被真正地内联。。。

在这里插入图片描述通过使用 inline 关键字,可以告诉编译器将该函数作为内联函数处理。

☃ 需要注意的是,内联函数适用于简单短小的函数,且在多处调用的情况下才能发挥优势。对于复杂的函数或只在少数地方调用的函数,使用内联可能导致代码膨胀,反而降低性能。因此,在确定是否使用内联函数时,需要综合考虑函数的规模、调用频率以及性能需求等因素。

?当我们单纯的定义一个类,定义任何成员变量时,系统会为这个类开空间吗

在 C++ 中,一个类的对象大小至少为 1 字节,即使这个类没有任何成员变量。这是因为每个对象都必须在内存中占据至少一个字节的空间。
这个字节通常用于对象的地址,也就是对象所在内存地址的第一个字节。即使这个字节不存储有效数据,但是它也是必需的,因为它用于确定对象在内存中的位置和边界。

类的访问限定操作符

在C++中,类的访问限定符用于控制类的成员变量和成员函数的访问权限。C++中为我们提供了三种访问限定符:public、private和protected。

1. public:

  • 成员变量和成员函数声明为public的可以在类的外部和内部被访问。
  • public成员可以通过对象直接访问或通过类的对象调用。
  • public成员在类的继承层次中也可以被派生类访问。

2. private:

  • 成员变量和成员函数声明为private的只能在类的内部被访问。
  • private成员不能通过对象直接访问,只能通过类的成员函数来访问。
  • private成员对于类的外部是不可见的。

3. protected:

  • 成员变量和成员函数声明为protected的可以在类的内部被访问。
  • protected成员在类的继承层次中可以被派生类访问,但对于类的外部是不可见的。
  • protected成员不能通过对象直接访问,只能通过类的成员函数来访问。

默认情况下,C++中的类成员的访问限定符是private。这意味着如果没有显式地指定访问限定符,那么成员变量和成员函数都将被视为private成员。

代码演示:

#include <iostream>
using namespace std;

class MyClass {
public:
    int publicVar;
    void publicFunc() {
        cout << "publicFunc is called" << endl;
    }

protected:
    int protectedVar;
    void protectedFunc() {
        cout << "protectedFunc is called" << endl;
    }

private:
    int privateVar;
    void privateFunc() {
        cout << "privateFunc is called" << endl;
    }
};

int main() {
    MyClass obj;
    obj.publicVar = 1;
    obj.publicFunc();
    return 0;
}

在上面的代码中,我们定义了一个名为MyClass的类,并且使用了三种不同的访问限定符来限制成员的访问权限。在main函数中,我们创建了一个MyClass类的对象obj,并且访问了publicVar和publicFunc方法,因为它们都是公共成员。但是我们不能访问protectedVar、protectedFunc、privateVar和privateFunc方法,因为它们只能在类内部访问。如果尝试访问它们,编译器会报错。

通过使用不同的访问限定符,我们可以控制类的成员在何处可见和可访问。这有助于实现信息隐藏和封装的概念,使得类的实现细节对于外部用户来说是不可见的,从而提高代码的安全性和可维护性。

类的作用域

在C++中,类的作用域是指类中成员的可见范围。类的作用域可以分为两个部分:类的内部作用域和类的外部作用域。

  • 类的内部作用域:在类的内部,成员函数和成员变量可以直接访问类中的其他成员,无需使用作用域解析运算符::来限定。在成员函数中,可以直接访问该类的所有成员,包括私有、保护和公共成员。
  • 类的外部作用域:在类的外部,需要使用作用域解析运算符::来限定访问类中的成员。通过类名加上作用域解析运算符,可以访问该类的公共成员和静态成员。私有和保护成员无法在类外部直接访问。

在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。作用域操作符在博主在这里插入图片描述C++入门篇 有讲解

类的实例化

类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图。
在这里插入图片描述

类对象模型

类在内存中的存储模式如下:
在这里插入图片描述

在计算类对象的大小时,一般只需要考虑成员变量的大小,而不需要计算成员函数的大小。成员函数在对象中并不占据实际的内存空间,它们只是一组指向类的成员函数代码的指针。这些指针共享存储在类的静态区域中,并且对于每个类的所有对象来说是相同的。因此,成员函数不会影响类对象的大小。

总结起来,计算类对象的大小只需要考虑成员变量的大小,而成员函数和虚函数表对于类对象的大小没有直接影响。

this指针

在C++中,每个对象都有一个指向自己的指针,这个指针就是this指针。this指针是一个隐含于每个非静态成员函数中的特殊指针,它指向调用该函数的对象。在C++中,成员函数可以直接访问对象的数据成员,因为在成员函数内部,this指针指向当前对象的地址,通过this指针可以访问对象的所有成员变量和成员函数。

先来看一段简单的代码:

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, d2;
 d1.Init(2022,1,11);
 d2.Init(2022, 1, 12);
 d1.Print();
 d2.Print();
 return 0;
}

???Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?

在这里插入图片描述在C++中,对象在调用成员函数时,编译器会自动将该对象的地址作为this指针传递给成员函数。在Init函数中,通过this指针访问对象的成员变量,确保将值设置到正确的对象中。

因此,当d1调用Init函数时,Init函数内部的操作会通过this指针访问d1对象的成员变量,即将值设置到d1对象的_year、_month和_day成员变量中;同样,当d2调用Init函数时,Init函数内部的操作会通过this指针访问d2对象的成员变量,将值设置到d2对象的成员变量中。这样就实现了不同对象之间的区分。当然最后,当d1和d2调用Print函数时,会打印出各自的年月日信息。

只不过这些所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。在这里插入图片描述

在这里插入图片描述

this指针在C++中具有以下特性:

  1. this指针的类型是类类型的指针,即类类型* const。这意味着this指针是一个常量指针,指向当前对象的地址,不可以被修改。

  2. this指针只能在成员函数内部使用。它代表当前对象的地址,并且只有在成员函数内部才能访问到该指针。

  3. this指针本质上是成员函数的一个隐式形参。当对象调用成员函数时,编译器会将对象的地址作为实参传递给this指针,使得成员函数可以通过this指针来访问对象的成员变量和成员函数。

  4. this指针是成员函数的第一个隐含参数,一般情况下由编译器自动传递,不需要用户显式传递。

  5. 对象本身并不存储this指针,它只是在成员函数调用时被传递给this指针。

通过使用this指针,我们可以在成员函数内部访问对象的成员变量和函数,确保每个对象在调用成员函数时可以正确地操作自己的数据。this指针的存在使得对象的成员函数可以区分不同的对象,并在函数内部对各个对象进行操作。

在这里插入图片描述this指针是C++中一个非常重要的概念,也是面向对象编程中不可或缺的一部分。它可以让成员函数访问对象的成员变量和成员函数,避免命名冲突,返回对象本身的引用等。在使用this指针时,需要注意当前对象是否存在,以及函数内部是否正确处理对象的生命周期和有效性。

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

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

相关文章

JVM虚拟机的垃圾回收器(面试题)

1.什么是垃圾回收 垃圾回收主要说的是java会自动把程序在运行过程中产生的一些没有用的对象给回收掉&#xff0c;这样可以避免内存的浪费。 java主要是通过一个叫“根可达”的算法来识别这个对象是否可以被回收的&#xff0c;然后回收的算法也主要有三种&#xff1a;标记清除&a…

QT c++和qml交互实例

文章目录 一、demo效果图二、c和qml交互的基本方式1、qml访问C类对象 三、关键代码1、工程结构图2、c代码MainWindow.cppMainQuickView.cppStudentInfoView.cppStudentInfoModel.cpp 3、qml代码main.qmlMainQuickTopRect.qmlMainQuickMiddleRect.qmlMainQuickMiddleTableRect.q…

服务器cpu占用很高如何排查问题

前段时间&#xff0c;运维监控发现有个项目cpu占用很高&#xff0c;并且还在持续不断增长&#xff0c;服务不能正常响应&#xff0c;如下图&#xff1a; 在服务器上面安装了arthas&#xff0c;下载地址&#xff1a; https://alibaba.github.io/arthas/arthas-boot.jar 我使用了…

Linux stm32串口下载程序

一、工具 使用stm32flash进行串口下载 二、stm32flash安装 sudo apt-get install stm32flash 三、查看串口设备名称 先拔掉串口运行下面指令&#xff0c;获得所有设备名称,插上串口再运行一次&#xff0c;新增的就是串口设备名称&#xff0c;记住串口设备名称&#xff0c;以…

【信息论与编码】习题-判断题-第一部分

目录 判断题1. 对于N个对立并联信道&#xff0c;其信道容量CN2. 汉明码是一种线性分组码。3. 某一信源&#xff0c;不管它是否输出符号&#xff0c;只要这些符号具有某些概率特性&#xff0c;就有信息量。4. 若检错码的最小距离为dmin&#xff0c;则可以检测出任意小于等于dmin…

集团企业OA办公协同平台建设方案

一、企业对协同应用的需求分析 实现OA最核心、最基础的应用 业务流转&#xff1a;收/发文、汇报、合同等各种审批事项的业务协作与办理 信息共享&#xff1a;规章制度、业务资料、共享信息资源集中存储、统一管理 沟通管理&#xff1a;电子邮件、手机短信、通讯录、会议协作等…

期货日数据维护与使用_日数据维护_日数据更新

目录 写在前面&#xff1a; 下载日数据 下载“新增合约”日数据 下载“待更新合约”日数据 日数据文件 “选择日数据所在目录”按钮点击 “执行”按钮点击 sqlite3代码 按钮点击后执行的代码 子线程代码 写在前面&#xff1a; 本文默认已经创建了项目&#xff0c;如…

Archlinux下自启动rclone mount

路径&#xff1a; /etc/systemd/system/rclonemount.service [Unit] Descriptionrclonemount Requiresnetwork-online.target.wants Afteralist.service[Service] Typesimple ExecStartPre/bin/mkdir -p /media ExecStart/usr/bin/rclone mount \aliyun: /media \--config /ro…

Docker学习与应用(五)-DockerFile

1、DockerFile 1&#xff09;DockerFile介绍 dockerfile是用来构建docker镜像的文件&#xff01;命令参数脚本&#xff01; 构建步骤&#xff1a; 1. 编写一个dockerfile文件 2. docker build 构建称为一个镜像 3. docker run运行镜像 4. docker push发布镜像&#xff08;D…

2024最新前端源码分享(附效果图及在线演示)

分享10款非常有趣的前端特效源码 其中包含css动画特效、js原生特效、svg特效以及小游戏等 下面我会给出特效样式图或演示效果图 但你也可以点击在线预览查看源码的最终展示效果及下载源码资源 粒子文字动画特效 基于canvas实现的粒子文字动画特效 会来回切换设定的文字特效 图…

Docker学习与应用(四)-容器数据卷

1、容器数据卷 1&#xff09;什么是容器数据卷 docker的理念回顾 将应用和环境打包成一个镜像&#xff01; 数据&#xff1f;如果数据都在容器中&#xff0c;那么我们容器删除&#xff0c;数据就会丢失&#xff01;需求&#xff1a;数据可以持久化 MySQL&#xff0c;容器删…

java推荐系统:好友推荐思路

1.表的设计 表里面就两个字段&#xff0c;一个字段是用户id&#xff0c;另外一个字段是好友id&#xff0c;假如A跟B互为好友&#xff0c;那在数据库里面就会有两条数据 2.推荐好友思路 上面的图的意思是&#xff1a;h跟a的互为好友&#xff0c;a跟b&#xff0c;c&am…

webgl调试之排查内存泄漏

内存泄漏自然而然是要看内存是不是涨了 然后我们如何确认泄露了呢&#xff0c;我们需要把代码梳理清楚&#xff0c;知道哪个时机&#xff0c;在delete&#xff0c;在create&#xff0c;那么这个时候&#xff0c;按道理&#xff0c;delete了n个对象&#xff0c;create了N个对象&…

[Excel]如何找到非固定空白格數列的條件數據? 以月份報價表單為例

在群組中看到上述問題&#xff0c;研判應是一份隨月份變動的產品報價表單&#xff0c;空白欄可能表示該月份價格與上個月份一致。這個問題是需要取得最近一次單價和倒數第二次單價&#xff0c;常用且實務的excel案例值得紀錄。 最近一次單價: INDEX($B2:$G2,1,LARGE(IF(ISBLAN…

贯穿设计模式-享元模式思考

写享元模式的时候&#xff0c;会想使用ConcurrentHashMap来保证并发&#xff0c;没有使用双重锁会不会有问题&#xff1f;但是在synchronize代码块里面需要尽量避免throw异常&#xff0c;希望有经验的同学能够给出解答&#xff1f; 1月6号补充&#xff1a;没有使用双重锁会有问…

【Qt- C++ Qml 交互】

Qt编程指南 VX&#xff1a;hao541022348 ■ 将C对象注册到 QML中&#xff0c;在QML使用C对象&#xff08;Q_INVOKABLE宏&#xff09;■ C对象注册到元对象系统■ Q_INVOKABLE 宏■ 演示步骤 ■ 将C对象注册到 QML中&#xff0c;在QML使用C对象&#xff08;Q_PROPERTY宏 属性绑定…

SpringCloud系列篇:核心组件之负载均衡组件

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于SpringCloud的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.负载均衡组件是什么 二.负载均衡…

PDF文档转换工具箱流量主小程序开发

PDF转换小助手&#xff0c;不仅是文件格式转换的利器&#xff0c;更是一位得力的助手。它精通PDF与各类文档间的自由转换&#xff0c;如Word、Excel、PowerPoint等。 转换选项丰富多样&#xff0c;满足您对文件保护、页面设置、图像品质等细致要求。处理大量文件&#xff1f;…

软件工程:数据流图相关知识和多实例分析

目录 一、数据流图相关知识 1. 基本介绍 2. 常用符号 3. 附加符号 二、数据流图实例分析 1. 活期存取款业务处理系统 2. 工资计算系统 3. 商业自动化系统 4. 学校人事管理系统 5. 教材征订系统 6. 高考录取统分子系统 7. 订货系统 8. 培训中心管理系统 9. 考务处…

模仿Activiti工作流自动建表机制,实现Springboot项目启动后自动创建多表关联的数据库与表的方案

文/朱季谦 熬夜写完&#xff0c;尚有不足&#xff0c;但仍在努力学习与总结中&#xff0c;而您的点赞与关注&#xff0c;是对我最大的鼓励&#xff01; 在一些本地化项目开发当中&#xff0c;存在这样一种需求&#xff0c;即开发完成的项目&#xff0c;在第一次部署启动时&…