类的认识和定义

article/2025/3/19 22:26:48

前言

C++为啥要引入类这个概念呢,以C实现栈为例说明。

typedef int STDataType;
typedef struct Stack
{
. . . .int top;
. . . .STDataType* data;
. . . .int capacity;
}Stack;
void StackInit(Stack* ps); //栈的初始化
void StackDestory(Stack* ps); //栈的销毁
void StackPush(Stack* ps, STDataType x); //入栈
void StackPop(Stack* ps); //出栈
STDataType StackTop(Stack* ps); //栈顶

假设C++大佬带了几个实习生,结果实习生这样获取栈顶元素

Stack st;
printf("%d ", st.data[st.top]);

结果的得不到栈顶元素,反而得到的是一个随机值,实习生就会跑过来问大佬了,这个栈不好用啊我这怎么没得到栈顶元素啊,反而得到一个随机值。大佬给他解释半天栈只能通过调用给你的接口来实现…第一个实习生听懂了,过两天又有个实习生跑过来问这个问题,大佬有耐心给他解释,过几天又有个实习生跑过来问这个问题,问的人多了,大佬就开始反思了,C这个语言有缺陷,能不能在C基础上解决这个问题呢于是对C进行了强化命名C++,引入类,来更好的封装,干脆把成员变量保护起来不让用,只能调用我的接口来实现。

1.面向过程和面向对象初步认识

C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。
C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

2.类的引入

C语言中,结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。 在c++中struct升级成了类,类和结构体不同的是类除了可以定义变量,还可以定义方法/函数。

3.类的定义

//struct className
class className
{// 类体:由成员函数和成员变量组成}; // 一定要注意后面的分号

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

也可以用struct定义类,二者区别是C++需要兼容C语言,所以C++中struct可以当成结构体去使用。另外C++中struct还可以用来定义类。和class是定义类是一样的,区别是struct的成员默认访问方式是public,class是struct的成员默认访问方式是private。

类的两种定义方式:

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

class student
{
public://(公有的)  --- 参考下面访问限定符讲解void StudentInit(const char* name, const char* gender, int age){strcpy(_name, name);strcpy(_gender, gender);_age = age;}void printf(){cout << _name << " "<< _gender << " "<< _age << endl;}
private://(私有的)char _name[20];char _gender[20];int _age;
};

2. 声明放在.h文件中,类的定义放在.cpp文件中

.h 文件中

class student
{
public://(公有的)void StudentInit(const char* name, const char* gender, int age);void printf();
private://(私有的)char _name[20];char _gender[20];int _age;
};

.cpp文件中

	void student::StudentInit(const char* name, const char* gender, int age){strcpy(_name, name);strcpy(_gender, gender);_age = age;}void student::printf(){cout << _name << " "<< _gender << " "<< _age << endl;}

一般情况下,更期望采用第二种方式。

4.访问限定符

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

【访问限定符说明】

  1. public修饰的成员在类外可以直接被访问
  2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
  3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  4. class的默认访问权限为private,struct为public(因为struct要兼容C)

5.类的大小

我们通过一组程序来计算类的大小:

//类中既有成员变量,又有成员函数
class student1
{
public:void StudentInit(const char* name, const char* gender, int age){}void printf(){}
private://(私有的)int _age;
};//类中仅有成员函数
class student2
{
public:void StudentInit(const char* name, const char* gender, int age){}void printf(){}
};
//类中什么都没有 -- 空类
class student3
{
};int main()
{cout << sizeof(student1) <<endl;cout << sizeof(student2) <<endl;cout << sizeof(student3) <<endl;return 0;
}

运行结果:
在这里插入图片描述
由此可见一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类。

6.this指针

对于类有这样一个问题:student类中有StudentInit与printf两个成员函数,函数体中没有关于不同对象的区分,那当s1调用printf函数时,该函数是如何知道应该设置s1对象,而不是设置s2对象呢?

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

class student
{
public:void StudentInit(const char* name, const char* gender, int age){strcpy(_name, name);strcpy(_gender, gender);_age = age;}//void printf(student* const this)   --- 定义成员函数时不能显示声明形参thisvoid printf(){cout << _name << " "<< _gender << " "<< _age << endl;//cout << this->_name << " " <<this->_gender << " " << this->_age << endl;//成员函数内部可以这样用,但通常不这样用}
private://(私有的)char _name[20];char _gender[20];int _age;
};
int main()
{student s1;student s2;s1.StudentInit("张三", "男", 20);  //s.StudentInit(&s,"张三", "男", 20);s2.StudentInit("李四", "男", 10);s1.printf();  //s.printf(&s)  --- 调用成员函数时,不能显示传实参给thiss2.printf();return 0;
}

this指针特性:

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

以下两篇文章和本文连贯性较强,建议一起看。点下面文字即可跳转对应文章。
构造函数和析构函数
拷贝构造函数与运算符重载


http://chatgpt.dhexx.cn/article/TKie6mJW.shtml

相关文章

Python类的定义

类的定义&#xff1a;我们把对象比作一个“饼干”&#xff0c;类就是制造这个饼干的模具。通过类定义数据类型的属性和方法&#xff0c;也就是说&#xff0c;“类将行为和状态打包在一起”。 类的结构 方法&#xff08;函数&#xff09;..............行为 属性&#xff08;…

java类的定义

目录 一、概念二、使用1.成员变量2.成员方法3.权限修饰符4.静态方法 三、重写toString方法 一、概念 我们不能将一个事物称之为一类事物&#xff0c;例如一只鸟我们不能称为鸟类&#xff0c;但是我们需要给一类事物统称&#xff0c;例如大雁&#xff0c;麻雀&#xff0c;燕子&…

C++ 类的定义与使用

十二、类与对象 对象&#xff1a;就是我们生活中的具体事物&#xff0c;看得见摸得到&#xff0c;有一定的属性和行为或操作方式 面向对象&#xff1a;是一种软件的开发方法&#xff0c;对象所指的是计算机系统中的某一个成分。在面向对象程序设计中&#xff0c;对象包含两个…

4.类的定义,变量类型,方法类型

文章目录 1.类的概念1.1 如何创建一个类1.2 如何定义一个类1.2.1变量1.2.2 方法 2.对象3.类定义使用实例4.理解类和对象的关系4.1.一个java程序和类之间的关系 5.细节知识分析5.1.类与类的关系5.2.变量和变量区别5.3.方法的区别5.4.类方法和类变量的特点 1.类的概念 类java是基…

关于类的定义

类的定义 类的概念如何定义类修饰符 类的概念 1、类是把事物的数据与相关功能封装到一起&#xff0c;形成一种特殊的数据结构&#xff0c;用以表达真是事物的一种抽象&#xff1b;而对象则是实际存在的属该类事物的具体个体&#xff0c;因而也称为实例&#xff08;instance&am…

python 爬虫爬取疫情数据,爬虫思路和技术你全都有哈(一)

python 爬虫爬取疫情数据&#xff0c;爬虫思路和技术你全都有哈&#xff08;二、数据清洗及存储&#xff09; 爬起疫情数据&#xff0c;有两个网址&#xff1a; 1、百度&#xff1a;链接 2、丁香园疫情&#xff1a;链接 在这两个中&#xff0c;丁香园的爬虫相对简单一点&#…

采用python爬虫爬取数据然后采用echarts数据可视化分析

前言&#xff1a;采用python爬虫爬取天气数据然后采用echarts数据可视化画图分析未来天气变化趋势 从获取数据到可视化的流程 &#xff08;熟悉爬虫爬取数据然后数据可视化这个过程&#xff09; 一、python爬取未来8-15天的天气数据 1、导入用到的一些python第三方库 imp…

python网络爬虫爬取数据,python全网爬取内容

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python网络爬虫爬取数据&#xff0c;利用python爬取数据&#xff0c;现在让我们一起来看看吧&#xff01; 网络爬虫&#xff0c;就是按照一定规则自动访问互联网上的信息并把内容下载下来的程序或脚本。 在整个的Python…

Python爬虫爬取网页数据并存储(一)

Python爬虫爬取网页数据并存储&#xff08;一&#xff09; 环境搭建爬虫基本原理urllib库使用requests库使用正则表达式一个示例 环境搭建 1.需要事先安装anaconda&#xff08;或Python3.7&#xff09;和pycharm *anaconda可在中科大镜像下下载较快 2.安装中遇到的问题&#x…

【用Java爬取网页图片——爬虫爬取数据】

用Java爬取网页图片——爬虫爬取数据 1、在创建项目中导入jsoup 2、创建一个保存下载图片的路径 3、使用URL读取网页路径&#xff0c;jsoup读取网页内容 4、利用属性标签获取图片连接块 5、因为该路径没有http&#xff1a;头&#xff0c;用StringBuilder增加 5、完善下载路径…

爬虫爬取数据

打开爬取工具页面,使用爬虫工具列表: 开始节点 仅仅是爬虫的起点,所有流程图必须有该节点。 爬取节点 该节点用于请求HTTP/HTTPS页面或接口 请求方法:GET、POST、PUT、DELETE等方法 URL: 请求地址 延迟时间:单位是毫秒,意思是爬取之前延迟一段时间在执行抓取 超时时间:网…

手把手教会 爬虫爬取json数据

提示&#xff1a;本章爬取练习的url地址 发现曲谱 (yoopu.me) 前言 我们学爬虫&#xff0c;有时候想要的数据并不在html文本里面&#xff0c;而是通过js动态渲染出来的。 如果我们需要爬取此类数据的话&#xff0c;我们该怎么办呢&#xff1f; 请读者接着往下看&#xff1a…

六个步骤学会使用Python爬虫爬取数据(爬虫爬取微博实战)

用python的爬虫爬取数据真的很简单&#xff0c;只要掌握这六步就好&#xff0c;也不复杂。以前还以为爬虫很难&#xff0c;结果一上手&#xff0c;从初学到把东西爬下来&#xff0c;一个小时都不到就解决了。 Python爬虫六部曲 第一步&#xff1a;安装requests库和BeautifulS…

网络爬虫入门:网络爬虫的目的,企业获取数据的方式,可以用于做爬虫的程序语言,爬虫爬取数据的步骤

目录 爬取数据的目的&#xff1a; 1.获取大量数据&#xff0c;用于做数据分析 2.公司项目的测试数据&#xff0c;公司业务所需数据 企业获取数据的方式 1.公司自有数据 2.第三方数据平台购买&#xff08;数据堂&#xff0c;贵阳大数据交易所&#xff09; 3.爬虫爬取数据…

利用爬虫爬取数据集

相信大家在学习tensorflow的过程中&#xff0c;会想要自己动手来试试加载我们的数据集&#xff0c;而不再局限于从datasets上下载数据集。但是往往一个模型的训练就需要很庞大的数据集&#xff0c;因此写下这篇博客教大家如何用爬虫爬取图片&#xff0c;制作自己的数据集&#…

微信小程序实名认证接口_人脸核身接口整理

一、微信小程序实名认证接口_人脸核身接口整理 开场一个字&#xff1a; 悲观。目前实名接口&#xff0c;人脸识别接口开放度不高。“实名信息授权”已经回收。 二、人脸核身接口 1.使用条件 需要现申请通过才能使用。 目前开放的分类不多&#xff0c;并且还需要行业资质。 …

微信小程序—人脸识别

1.首先你要有一个可以就行人脸识别的服务器&#xff0c;然后就是上传到百度云&#xff0c;百度云人脸识别的API接口全面升级到V3版本&#xff0c;并进行开放测试 2.wxml代码 <camera device-position"{{sxt}}" flash"off" binderror"error" s…

微信小程序实现人脸识别注册登录

前言 这是一篇关于一个原创微信小程序开发过程的原创文章。涉及到的核心技术是微信小程序开发方法和百度云人脸识别接口。小程序的主体是一个用于个人密码存储的密码管理器&#xff0c;在登陆注册阶段&#xff0c;需要调用百度云人脸识别接口以及百度云在线人脸库的管理接口。…

C# Winform开发人脸识别小程序 (基于百度接口)

目录 一、设计思路1、背景2、简介3、用到的技术4、设计功能一&#xff1a;用户注册功能概述功能示意图时序图 功能二&#xff1a;人脸识别功能概述功能示意图时序图 二、实现1、环境准备2、百度接口配置3、技术准备4、代码实现功能一&#xff1a;用户注册功能二&#xff1a;人脸…

python人脸检测与微信小程序_微信小程序人脸识别功能

本文档以微信小程序为例&#xff0c;微信小程序开发人脸核身功能需要两个申请&#xff1a;腾讯云申请人脸识别服务和小程序申请人脸识别服务&#xff08;注意&#xff1a;只有符合以下条件的机构才能在小程序端申请&#xff09; 政务&#xff1a;政府机构或事业单位 金融&…