『C++成长记』类和对象

 🔥博客主页:小王又困了

📚系列专栏:C++

🌟人之为学,不日近则日退 

❤️感谢大家点赞👍收藏⭐评论✍️


目录

一、类的引入

二、类的定义

三、类的访问限定符

四、类的作用域

五、类的实例化

六、this指针

📒6.1this指针的引出

📒6.2 this指针的特性


🗒️前言:

🎀面向过程

     C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。用洗衣服举例。

🎀面向对象

     C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完 成。对于洗衣服这件事,C++设置了四个对象:人、衣服、洗衣粉、洗衣机。整个洗衣服的过程就变成了:人将衣服放进洗衣机、倒入洗衣粉、启动洗衣机,洗衣机就会完成洗衣过程并甩干。整个洗衣服的过程,是人、衣服、洗衣粉、洗衣机四个对象之间交互完成的,人不需要关心洗衣机具体是如何洗衣服的。

一、类的引入

     C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如: 之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现, 会发现struct中也可以定义函数。

💌C语言版

struct Stack
{
    int* arr;
    int capacity;
    int size;
};

struct Stack s;//声明一个结构体变量

void StackInit(struct Stack* ps);

void StackPush(struct Stack* ps,int x);

     在C语言中,数据和方法分离,传递参数才能访问数据,没有对类型重定义只能写成struct Stack。函数名必须区分,要写成StackInit,在一个程序中如果有别的结构,例如:链表,就无法区分。

💌C++版

struct Stack
{
    //函数
    void Init()
    {}
 	void Push()
    {}

    //变量
    int* arr;
    int capacity;
    int size;
};

     在C++中,类名就是类型,不需要加struct,而且不仅可以定义变量,还可以定义函数。变量可以通过.去调用类里面的函数。

二、类的定义

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

     class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略

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

🎀类的两种定义方式:

  • 声明和定义全部放在类体中
//定义一个人的类
class Person
{
    //成员函数——显式基本信息
    void showInfo()
    {
        cout << _name << "-" << _sex << "-" << _age << "-" << endl;
    }
    //成员变量
    char* _name;//姓名
    char* _sex;//性别
    int _age;//年龄
};

注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理,最终是否真的是内联,还是由编译器说了算。

  • 类声明放在.h文件中,成员函数定义放在.cpp文件中
Person.h文件
//定义一个人的类
class Person
{
    //成员函数——显式基本信息
    void showInfo();

    //成员变量
    char* _name;//姓名
    char* _sex;//性别
    int _age;//年龄
};
Person.cpp文件
#include "Person.h"

void Person::showInfo()
{
    cout << _name << "-" << _sex << "-" << _age << "-" << endl;
}

注意:成员函数名前需要加类名: :,告诉编译器这个函数属于哪个类域。长的函数声明和定义分离,短的函数在类中定义。

三、类的访问限定符

     C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选择性的将其接口提供给外部的用户使用。C++提供了三种限制权限的访问限定符:publicprotectedprivate

🎀访问限定符说明

  • public修饰的成员在类外可以直接被访问(通过对象.访问)
  • protectedprivate修饰的成员在类外不能直接被访问(此处protected和private是类似的)
  • 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,如果后面没有访问限定符,作用域就到 } 即类结束。
  • 如果后面没有访问限定符,作用域就到 } 即类结束。
  • class的默认访问权限为private,struct的默认访问权限为public(因为struct要兼容C)
  • 访问限定符可以修饰类中的成员变量、成员函数、内部类、重命名类型。友元函数的声明不受访问限定符的限制。

注意:类定义数据一般是私有的 。

四、类的作用域

     类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要::作用域限定符指明成员属于哪个类域。不同的类域里面可以定义同名变量。

//定义一个人的类
class Person
{
    //成员函数
    void Person();
    //成员变量
    char* _name;//姓名
    char* _sex;//性别
    int _age;//年龄
};

// 这里需要指定PersonInfo是属于Person这个类域
void Person::PersonInfo()
{
    cout << _name << "-" << _sex << "-" << _age << "-" << endl;
}

     如上面的成员函数PersonInfo,对于函数体中出现的变量_name等,编译器会先在当前函数的局部域中搜索,如果没有找到,接下来会到对应的类域里面去搜索,当类域里面也没有的时候,最后回到全局区搜索,如果全局也没有,编译就会报错。

五、类的实例化

用类型创建对象的过程,称为类的实例化。

     类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它。类和对象的关系可以看成,拿图纸建房子的过程,图纸就是类,建出来的一栋栋房子,就是一个个的对象。

     一个类可以实例化出多个对象,就像一个图纸,可以建成很多房子一样,实例化出的对象占用实际的物理空间,存储类成员变量。

class Person
{
    //成员函数
    void Person::PersonInfo()
    
    //成员变量
    char* _name;//姓名
    char* _sex;//性别
    int _age;//年龄
};

int main()
{
    Person p1;//用类实例化一个对象p1
    Person p2;//用类实例化一个对象p2
    p1._name = "张三";
    p1._sex = "男";
    p1._age = 19;
    return 0;
}

六、this指针

📒6.1this指针的引出

     我们先观察下面的代码 

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);//给d1初始化化
    d2.Init(2022, 1, 12);//给d2初始化
    d1.Print();//调用Print函数
    d2.Print();//调用Print函数
    return 0;
}

对于上述类,有这样的一个问题:

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

C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏 的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量” 的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编 译器自动完成。

    void Print()
    {
        cout << _year << "-" << _month << "-" << _day << endl;
    }


    void Print(Date* const this)
    {
        cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
    }

📒6.2 this指针的特性

  1.  this指针的类型:类类型* const,即成员函数中,不能给this指针赋值。
  2.  只能在“成员函数”的内部使用.
  3.  this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给 this形参。所以对象中不存储this指针。
  4.  this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传 递,不需要用户传递。

本次的内容到这里就结束啦。希望大家阅读完可以有所收获,同时也感谢各位读者三连支持。文章有问题可以在评论区留言,博主一定认真认真修改,以后写出更好的文章。你们的支持就是博主最大的动力。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

基于V100下Llama2-Atom大模型微调

文章目录 大规模的中文数据预训练模型部署模型微调Step1: 环境准备Step2: 数据准备Step3: 微调脚本Step4: 加载微调模型 一些BUG 大规模的中文数据预训练 原子大模型Atom在Llama2的基础上&#xff0c;采用大规模的中文数据进行持续预训练&#xff0c;包含百科、书籍、博客、新…

⑩⑦【MySQL】锁:全局锁、表级锁、行级锁

个人简介&#xff1a;Java领域新星创作者&#xff1b;阿里云技术博主、星级博主、专家博主&#xff1b;正在Java学习的路上摸爬滚打&#xff0c;记录学习的过程~ 个人主页&#xff1a;.29.的博客 学习社区&#xff1a;进去逛一逛~ MySQL锁 ⑩⑦【MySQL】锁&#xff1a;全局锁、…

官宣!Sam Altman加入微软,OpenAI临时CEO曝光,回顾董事会‘’政变‘’始末

11月20日下午&#xff0c;微软首席执行官Satya Nadella在社交平台宣布&#xff0c;“微软仍然致力于与 OpenAI的合作伙伴关系。同时欢迎Sam Altman 和 Greg Brockman 及其团队加入微软&#xff0c;领导一个全新的AI研究团队”。 Sam第一时间对这个消息进行了确认。 此外&…

【机器学习】对比学习(contrastive learning)

对比学习是一种机器学习技术&#xff0c;算法学习区分相似和不相似的数据点。对比学习的目标是学习数据的表示&#xff0c;以捕捉不同数据点之间的基本结构和关系。 在对比学习中&#xff0c;算法被训练最大化相似数据点之间的相似度&#xff0c;并最小化不相似数据点之间的相似…

LOJ #10134. 「一本通 4.4 练习 1」Dis

分析 根据数据范围分析一下复杂度&#xff0c;Floyd和dj算法都必爆。 发现题目说的是树&#xff0c;还是边还是双向的&#xff08;树本身就是无向的&#xff0c;连通无回路的无向图叫做无向树&#xff0c;简称树。如果题目说了树&#xff0c;那么默认边就是双向的&#xff09…

优思学院|现代质量管理实践与六西格玛方法论如何融合?

企业要解决质量问题必然需要涉及管理&#xff0c;然而&#xff0c;如果仅仅将六西格玛法视为一种质量管理方法&#xff0c;必定会导致六西格玛管理法的失败。六西格玛法是一种具有特定战略性的管理方法&#xff0c;它涉及到市场、顾客、产品、服务、流程、质量、价值链以及财务…

利用多核的Rust快速Merkle tree

1. 引言 利用多核的Rust快速Merkle tree&#xff0c;开源代码见&#xff1a; https://github.com/anoushk1234/fast-merkle-tree&#xff08;Rust&#xff09; 其具有如下属性&#xff1a; 可调整为任意高度构建root复杂度为O(n)提供了插入和获取叶子节点的方法获取某叶子节…

centos7 利用nc命令探测某个tcp端口是否在监听

脚本 # 安装nc yum install -y ncnc -vz 192.168.3.128 60001 if [ $? -eq 0 ]; thenecho "tcp succeed" elseecho "tcp failed" fi nc -vz 192.168.3.128 60001 探测192.168.3.128服务器上60001 tcp端口, -vz说明是探测TCP的 端口开启的情况 执行…

用不用Microsoft Defender是你的自由,但不用最好也得有替代品

Microsoft Defender是预装在Windows 11操作系统上的重要安全工具。安全套件已完全集成到操作系统中&#xff0c;以保护你的系统免受恶意软件的攻击&#xff0c;但并不是每个人都喜欢它。你是否更愿意安装另一种防病毒/反间谍软件&#xff0c;以将Microsoft Defender推向绝境&am…

ATA-304功率放大器的电子实验案例(案例合集)

ATA-304功率放大器凭借其优异的指标参数受到不少电子工程师的喜欢&#xff0c;其在电子实验中的应用也非常频繁&#xff0c;下面为大家整理出ATA-304功率放大器的应用案例合集&#xff0c;希望能对领域内各位工程师、研究人员有所帮助。 案例一&#xff1a;ATA-304功率放大器在…

并行与分布式 第4章 数据级并行:向量体系结构和GPU

文章目录 并行与分布式 第4章 数据级并行&#xff1a;向量体系结构和GPU4.1 什么叫数据级并行4.1.1 数据级并行与SPMD4.1.2数据级并行——传统器件的问题4.1.3 数据级并行——向量体系结构和GPU 4.2 向量体系结构4.2.1 向量以及计算方式4.2.2 向量体系结构4.2.3 向量运算的执行…

如何在公网环境下使用内网穿透工具实现用ipad pro进行代码开发

文章目录 前言1. 本地环境配置2. 内网穿透2.1 安装cpolar内网穿透(支持一键自动安装脚本)2.2 创建HTTP隧道 3. 测试远程访问4. 配置固定二级子域名4.1 保留二级子域名4.2 配置二级子域名 5. 测试使用固定二级子域名远程访问6. iPad通过软件远程vscode6.1 创建TCP隧道 7. ipad远…

解锁数据库运维秘籍:掌握AntDB-T动态共享内存,提升进程间通信效率

动态共享内存是AntDB数据库通信的重要手段&#xff0c;本文主要阐述AntDB-T数据库动态共享内存的实现原理、实现方式与使用方法。 AntDB-T数据库是一款企业级通用分布式关系型数据库&#xff0c;其数据库内核是基于进程模型实现的&#xff0c;因此进程间通信&#xff08;IPC&am…

撸源代码破冰杀手锏(一):Spring Security系列

一: 禅悟人生,码砖破冰感悟 二: Spring Security安全阐述 忙着去耍帅,后期补充完整.................

腾讯云服务器标准型S5实例CPU性能如何?配置特性说明

腾讯云服务器CVM标准型S5实例具有稳定的计算性能&#xff0c;CVM 2核2G S5活动优惠价格280.8元一年自带1M带宽&#xff0c;15个月313.2元、2核4G配置748.2元15个月&#xff0c;CPU内存配置还可以选择4核8G、8核16G等配置&#xff0c;公网带宽可选1M、3M、5M或10M&#xff0c;腾…

日期格式转化成星期几部署到linux显示英文

异常收集 原因&#xff1a;解决办法仰天大笑出门去&#xff0c;我辈岂是蓬蒿人 传入一个时间获取这个时间对应的是星期几&#xff0c;在开发环境&#xff08;window系统&#xff09;中显示为星期几&#xff0c;部署到服务器&#xff08;linux系统&#xff09;中会显示英文的时间…

什么是单片机?聊聊它的历史

前言 1946年2月15日&#xff0c;第一台电子数字计算机 ENIAC问世&#xff0c;这标志着计算机时代的到来。 ENIAC 是电子管计算机&#xff0c;时钟频率虽然仅有 100 kHz&#xff0c;但能在1s 的时间内完成 5000 次加法运算。与现代的计算机相比&#xff0c;ENIAC有许多不足&am…

腾讯云标准型s5和s6有什么区别?CPU处理器有差异吗?

腾讯云服务器CVM标准型S5和S6有什么区别&#xff1f;都是标准型云服务器&#xff0c;标准型S5是次新一代云服务器规格&#xff0c;标准型S6是最新一代的云服务器&#xff0c;S6实例的CPU处理器主频性能要高于S5实例&#xff0c;同CPU内存配置下的标准型S6实例要比S5实例性能更好…

KyLin离线安装OceanBase

去OceanBase下载若干文件 1 首先安装ob-deploy-2.3.1-2.el7.x86_64.rpm rpm -ivh ob-deploy-2.3.1-2.el7.x86_64.rpm# 运行此命令的时候他会报错 RPM should not be used directly install RPM packages, use Alien instead! 这个需要用Alien去转换为deb的包&#xff0c;不…

Linux中,查看Tomcat版本、如何查看Tomcat版本

方法 在tomcat的bin目录下&#xff0c;执行version.sh命令即可 结果