从C到C++ | 类和对象(上)

目录

类的引入

类的定义

类的访问限定符

类的定义方式

类的作用域

类的实例化

this指针


类的引入

C语言的struct结构体中只能定义成员变量,在C++中,struct结构体不仅能定义成员变量,还能定义成员函数。比如,在C语言中,实现一个顺序表,我们需要定义一个结构体,结构体里面存成员变量,结构体外定义功能函数:

typedef int SLDateType;
typedef struct SeqList
{SLDateType* a;int size;int capacity;
}SL;//开辟顺序表
void SeqListInit(SL* s);
//销毁顺序表
void SeqListDestroy(SL* s);
//检查顺序表容量
void SeqListCheckCapacity(SL* s);
//打印顺序表
void SeqListPrint(SL* s);
// 对数据的管理:增删查改 
void SeqListPushBack(SL* s, SLDateType x);
void SeqListPushFront(SL* s, SLDateType x);
void SeqListPopFront(SL* s);
void SeqListPopBack(SL* s);// 顺序表查找
int SeqListFind(SL* s, SLDateType x);
// 顺序表在pos位置插入x
void SeqListInsert(SL* s, int pos, SLDateType x);
// 顺序表删除pos位置的值
void SeqListErase(SL* s, int pos);

然而在C++中,我们可以这样实现:

struct SeqList
{typedef int SLDateType;//以下是成员函数//开辟顺序表void Init();//销毁顺序表void Destroy();//检查顺序表容量void Capacity();//打印顺序表void Print();// 对数据的管理:增删查改 void PushBack(SLDateType x);void PushFront(SLDateType x);void PopFront();void PopBack();// 顺序表查找int Find(SLDateType x);// 顺序表在pos位置插入xvoid Insert(int pos, SLDateType x);// 顺序表删除pos位置的值void Erase(int pos);// 成员变量SLDateType* a;int size;int capacity;
};

通过直观的对比,我们可以发现:

1.在C++中,函数可以写在结构体里,可以称其为结构体的成员函数。

2.在C++中,函数参数列表中不用再传结构体本身。

3.在C++中,函数的名称可以不用再害怕冲突,例如Print打印成员变量的函数,在结构体里可以命名为Print,结构体外也可以定义一个名为Print()的函数,结构体里的函数和结构体外的函数不冲突。

而上面的结构体,在C++中更喜欢用class代替,并且在C++中更喜欢将其称为“类”。


类的定义

class ClassName
{// 类的成员
};

class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略。 类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者 成员函数。

上面的结构体,用类来定义则是:

class SeqList
{typedef int SLDateType;
public://开辟顺序表void Init();//销毁顺序表void Destroy();//检查顺序表容量void Capacity();//打印顺序表void Print();// 对数据的管理:增删查改 void PushBack(SLDateType x);void PushFront(SLDateType x);void PopFront();void PopBack();// 顺序表查找int Find(SLDateType x);// 顺序表在pos位置插入xvoid Insert(int pos, SLDateType x);// 顺序表删除pos位置的值void Erase(int pos);
private:// 成员变量SLDateType* a;int size;int capacity;
};

class的定义方式和struct的相比,可以很明显得发现class的定义方式了"public"和"private",这其实是“类的访问限定符”。


类的访问限定符

C++类的访问限定符有三种:{

        public(公有)

        protected(保护)

        private(私有)

}

  • public修饰的成员在类外可以直接被访问
  • protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
  • 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  • 如果后面没有访问限定符,作用域就到}即类结束。
  • 若类的结构体里没有声明访问限定符,则class的默认访问权限为private,struct为public(因为struct要兼容C)。

注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

在实际运用中,用到的大多数是public与protected限定符,private很少用到。


类的定义方式

类有两种定义方式:

1. 声明和定义全部放在类体中,要注意的是,成员函数如果在类中定义,编译器可能会将其当成内联函数处理。 

//test.h 类的声明和定义class test
{public: void print(){std::cout << " 声明和定义全部放在类体中 " << std::endl;}
};

 2.声明和定义分离,类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::

//test.h 类的声明
#include <iostream>
class test
{public: void print();
};
// test.cpp 类的定义
#include "test.h"void test::print()
{std::cout << "类的声明和定义分离" << std::endl;
}

类的作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。

// 这里以定义类的函数PeintPersonInfo的执行体为例class Person
{
public:void PrintPersonInfo();private:char _name[20];char _gender[3];int  _age;};// 这里需要指定PrintPersonInfo是属于Person这个类域
void Person::PrintPersonInfo(){cout << _name << " "<< _gender << " " << _age << endl;
}

类的实例化

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

  • 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;比如:入学时填写的学生信息表,表格就可以看成是一个类来描述具体学生信息。
  • 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量
    class Person
    {
    public:char _name[20];char _gender[3];int _age;
    };int main()
    {Person._age = 100;    // 编译失败:error C2059: 语法错误:“.”return 0;
    }

    Person类定义完后是没有空间的,只有将其实例化出对象后才能给其成员赋值,就像这样:

class Person
{
public:char _name[20];char _gender[3];int _age;
};int main()
{Person man;man._name = "Jack";man._gender = "man";man._age = 100;   return 0;
}

类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间。


this指针

this指针的引用:

首先定义一个日期类Date

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

this指针的特性:

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

 以上面日期类Date的Print()成员函数为例,编译器在处理时,会将Print()成员函数处理为:

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

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

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

相关文章

【CSS】设置0.5px的边框宽度

直接写border: 0.5px solid red; 这样在移动端可能会出现问题&#xff0c;下面说下解决办法&#xff1a; 直接上代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta http-equiv"X-UA-C…

STM32 内部 EEPROM 读写

STM32 的某些系列 MCU 自带 EEPROM。笔者使用的 STM32L151RET6 自带 16 KB 的 EEPROM&#xff0c;可以用来存储自定义的数据。在芯片选型时&#xff0c;自带 EEPROM 也可以作为一个考量点&#xff0c;省去了在外接 EEPROM 的烦恼。 下面简单介绍下 STM32 内部 EEPROM 的读写流…

【Linux下使用docker安装搭建DVWA】

0x01 关于 DAMN VULNERABLE WEB APPLICATION&#xff08;DVWA&#xff09; Damn Vulnerable Web Application (DVWA)(译注&#xff1a;可以直译为&#xff1a;"糟糕的"不安全Web应用程序)&#xff0c;是一个编码差的、易受攻击的 PHP/MySQL Web应用程序。 它的主要目…

网页在线预览编辑Office,支持doc/docx、xls/xlsx、ppt/pptx、pdf等格式

随着互联网技术的不断发展&#xff0c;越来越多的企业开始采用在线办公模式&#xff0c;微软Office Word 是最好用的文档编辑工具&#xff0c;然而doc、docx、xls、xlsx、ppt、pptx等格式的Office文档是无法直接在浏览器中直接打开的&#xff0c;如果可以实现Web在线预览编辑Of…

flink如何写入es

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、写入到Elasticsearch5二、写入到Elasticsearch7总结 前言 Flink sink 流数据写入到es5和es7的简单示例。 一、写入到Elasticsearch5 pom maven依赖 <d…

SpringBean的生命周期

SpringBean Bean的生命周期 1、首先需要明确bean对象与普通对象的区别: 对于普通的 Java 对象&#xff0c;当 new 的时候创建对象&#xff0c;然后该对象就能够使用了。一旦该对象不再被使用&#xff0c;则由 Java 自动进行垃圾回收。 而 Spring 中的对象是 bean&#xff0c;…

Gin 项目引入热加载

Gin 项目引入热加载 文章目录 Gin 项目引入热加载一、什么是热加载二、Air2.1 介绍2.2 特性特性&#xff1a;2.3 相关文档2.4 安装推荐使用 install.sh使用 go install 2.5 配置环境变量2.6 使用 三、Fresh3.1 介绍3.2 相关文档3.3 安装与使用 四、bee4.1 介绍4.2 相关文档4.3 …

天翼GPU-A10云主机安装英伟达CUDA12.2驱动并共享镜像

一、英伟达环境安装主要流程 1、下载安装对应系统版本nVidia驱动程序安装验证 2、CUDA开发套件安装验证 3、深度学习框架安装验证 4、容器化CUDA环境安装验证 5、制作天翼云主机私有镜像 6、分享镜像给其他用户&#xff0c;实现天翼云A10显卡英伟达驱动环境共享 二、详细…

Python 模块和包(1)

模块&#xff08;Modules&#xff09;&#xff0c;可以理解为是对代码更高级的封装&#xff0c;即把能够实现某一特定功能的代码编写在同一个文件中&#xff0c;其后缀名是.py。并将其作为一个独立的模块&#xff0c;这样既可以方便其它程序或脚本导入并使用&#xff0c;同时还…

WPF DatePicker与Calendar的使用和样式修改

什么是DatePicker&#xff0c;Calendar Calendar&#xff1a;日历&#xff08;显示年月日视图控件&#xff09;DatePicker&#xff1a;日期选择器&#xff08;是一个更小的控件&#xff0c;点击控件时才会弹出一个日历&#xff09; Calendar使用 常用属性 DisplayMode&#…

Linux_CentOS_7.9配置时区及NTPdate同步之简易记录

前言&#xff1a;ntpdate命令来自英文词组”NTPdate“的拼写&#xff0c;其功能是用于设置日期和时间。ntpdate命令能够基于NTP协议设置Linux系统的本地日期和时间&#xff0c;利用NTP服务的时钟过滤器来选择最优方案&#xff0c;大大提高了可靠性和精度&#xff0c;让系统时间…

2024,清洁家电卷向“全、智、廉、拓”与“出海”

文 | 智能相对论 作者 | 佘凯文 岁末&#xff0c;又到了一年一度盘点全年、筹划未来的重要节点。在今年经济大环境整体趋向稳定的背景中&#xff0c;许多行业都交还算过得去的成绩单&#xff0c;清洁家电正是其中一员。 特别是在整体家电大环境依旧严峻的前提下&#xff0c;…

Spring 面试题学习笔记整理

Spring 面试题学习笔记整理 Spring的理解IOC读取 xml注入 配置过程解析注解注入过程 高频 &#xff1a;IOC 理解 及原理 底层实现IoC的底层实现高频&#xff1a;Bean的生命周期&#xff08;图解&#xff09;高频&#xff1a;Bean的生命周期&#xff08;文解&#xff09;扩展知识…

【单片机项目实战】温度控制系统

本项目的主要作用是实现温度调控&#xff0c;通过设定一个预定的温度值&#xff0c;实现实时检测外界温度&#xff0c;当外界温度小于预定值时&#xff0c;电机正转&#xff0c;实现降温效果&#xff1b;当外界温度大于预定值时&#xff0c;电机反转&#xff0c;实现升温效果&a…

有详细一些的考研数学真题解析吗?

考研数学真题解析可以写得很详细&#xff0c;但是纸质资料可能受限于篇幅与排版等原因&#xff0c;没有把过程写得很详细。 但是&#xff0c;如果解析步骤不够详细的话&#xff0c;可能读者在看的时候就会因为其中某一个被省略的步骤而“卡壳”&#xff0c;进而需要花费很多额…

Linux驱动开发笔记(六):用户层与内核层进行数据传递的原理和Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/135384355 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

市场复盘总结 20240104

仅用于记录当天的市场情况,用于统计交易策略的适用情况,以便程序回测 短线核心:不参与任何级别的调整 昨日回顾: 方法一:指标选股 select * from dbo.ResultAll where 入选类型 like %指标选股% and 入选日期=20240104;方法二:趋势选股法 1、最低价持续3日上涨 2、均价…

YOLOv8改进 | 2023Neck篇 | 利用Gold-YOLO改进YOLOv8对小目标检测

一、本文介绍 本文给大家带来的改进机制是Gold-YOLO利用其Neck改进v8的Neck,GoLd-YOLO引入了一种新的机制——信息聚集-分发(Gather-and-Distribute, GD)。这个机制通过全局融合不同层次的特征并将融合后的全局信息注入到各个层级中,从而实现更高效的信息交互和融合。这种…

Spring之强大的DefaultListableBeanFactory

系列文章目录 如何查看类继承结构参考这里 文章目录 系列文章目录一、DefaultListableBeanFactory的类继承实现结构二、实现接口 一、DefaultListableBeanFactory的类继承实现结构 二、实现接口 AliasRegistry&#xff1a;支持别名功能&#xff0c;一个名字可以对应多个别名B…

【React系列】受控非受控组件

本文来自#React系列教程&#xff1a;https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzg5MDAzNzkwNA&actiongetalbum&album_id1566025152667107329) 一. refs 的使用 在React的开发模式中&#xff0c;通常情况下不需要、也不建议直接操作DOM原生&#xff0c;但是某些…