【C++入门第四期】类和对象 ( 上 )

news2024/12/25 0:30:39

  • 前言
  • 类的使用
  • 类的定义
    • 类的两种定义方式:
    • 成员变量名的定义建议
  • 类的访问限定符
  • 类的作用域
  • 类的实列化
  • 如何计算类的大小
    • 结构体内存对齐规则
  • this指针
    • this指针的特性

前言

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

C++是面向对象的语言,面向对象的三大特性:继承 ,封装 ,多态。但由于是入门文章,一开始就说把这些解释清楚未免太难为大家了。
请添加图片描述

大家先把类理解为:功能接口及数据包,需要那个功能直接调用其接口即可获得结果

使用接口时可以不知道的的具体实现,我们只需知道他的功能即可

类的使用

先别管实现,咱先看看猪跑(类的使用)

#include<iostream>
#include<string.h>

struct student//学生类
{
	student(const char* number ,const char* name)
	{
		strcpy(_number, number);
		strcpy(_name, name);
	}
	void print()
	{
		printf("姓名:%s  学号:%s\n", _name, _number);
	}
	char* number()
	{
		return _number;
	}
	char* name()
	{
		return _name;
	}
	char _number[15];
	char _name[15];
};
int main()
{
//类型为student ,对象名为zhang_san,()中是传参
	student zhang_san("20013", "张三");
	student li_si("20015", "李四");

	zhang_san.print();// .直接调用print接口即可
	//获取li_si对象中的_name变量中的数据
	std::cout << li_si._name << std::endl;
}

如上我定义了 student 类,里面有打印出学生信息的功能,及学生学号(_number)学生姓名(_name)

使用时我们只需定义 student对象即可使用 student 中的功能 , 及获取类中的变量数据
在这里插入图片描述
但是上面结构体的定义,在C++中更喜欢用class来代替

类的定义

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

};  //注意后面要加分号结束

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

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

类的两种定义方式:

  1. 成员函数声明和定义全部放在类体中
    需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数处理。
    在这里插入图片描述
    2. 类声明放在.h文件中,成员函数定义放在.cpp文件中

    注意:成员函数名定义前需要加类名:: ,表示该函数属于该类
    在这里插入图片描述
    一般情况下,更期望采用第二种方式

成员变量名的定义建议

在这里插入图片描述

类的访问限定符

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

在这里插入图片描述
访问限定符说明

  1. public修饰的成员在类外可以直接被访问
  2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的),等写继承的时候再说这俩有啥区别,说太多怕大家迷糊

访问权限作用域

  1. 从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
  2. 如果后面没有访问限定符,作用域就到 } 即类结束
    在这里插入图片描述
    如果类中没有写访问限定符
    class的默认访问权限为private,struct为public(因为struct要兼容C)

类的作用域

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

void car::print()//car::声明print()属于类car这个作用域
{
	cout << _name << _price << endl;
}
class car
{
public:
	void print();//声明
private:
	char _name[20] ;//车名
	char _price[20];//价格
};

类的实列化

类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没
有分配实际的内存空间来存储它;比如:4s店车入库时填写的表格,表格就可以看成是一个类,来描述车辆信息。

打个比方:类就像是建筑设计图(图只是一个构想或一个计划是虚拟的),并且我们可以用该图纸建造出多个一样实际的建筑。

类也一样在没生成对象前,他的功能是无法使用的,需要实列化出对象才行。

如下图,类需要定义出对象才能使用,用类类型创建对象的过程,称为类的实例化

class car
{
public:
	void print();

	char _name[20] ;//车名
	char _price[20];//价格
};
void car::print()//car::声明print()属于类car
{
	cout << "车名:" << _name << " 价格:" << _price << endl;
}
int main()
{
	//car.print();//会报错,类是不能直接使用的
	
	//正确方法
	car Byd_q;//定义出对象Byd_q 
	strcpy(Byd_q._name, "比亚迪秦");//向对象中写入数据
	strcpy(Byd_q._price, "99800");//向对象中写入数据
	Byd_q.print();//调用对象的成员含函数
}

如何定义对象

类名 对象名;

如何计算类的大小

class A1
{
public:
	void fun()
	{
		cout << "zhu_ge_bin";
	}
	int _a;
};
class A2
{
public:
	int _a;
};
class A3
{
public:

};
int main()
{
	A1 d1;
	A2 d2;
	A3 d3;
	printf("A1对象的大小为:%d\n", sizeof(d1));
	printf("A2对象的大小为:%d\n", sizeof(d2));
	printf("A3对象的大小为:%d\n", sizeof(d3));
}

如上图运行结果为
在这里插入图片描述
可以看出一个类的大小,实际就是该类中”成员变量”之和,当然要注意内存对齐

注意:空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类的对象

这里可能有人要问了那类中的函数不占空间吗?

1:每个对象所占用的存储空间只是该对象的数据部分所占用的存储空间,而不包括函数代码所占用的存储空间。(后面还会学虚基类指针和虚函数指针也属于数据部分现在可以暂时不用管)
2:类的成员函数本身不占用对象的内存空间。它们只是类的一部分,存储在代码段中。
3:因此,不同对象共享相同的函数代码,从而节省了内存空间。

结构体内存对齐规则

结构体内存对齐规则

  1. 第一个成员在结构体偏移量为0的地址处。
  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。
    注意:对齐数 = 编译器默认的对齐数 与 该成员大小两者之间的较小值,VS中默认的对齐数为8
  3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。
  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整
    体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

this指针

首先看以下代码,并运行

class car
{
public:
	void print()
	{
		cout << "车名:" << _name << " 价格:" << _price << endl;
	}
	void Init(const char* name , const char* price)
	{
		strcpy(_name , name);//写入数据
		strcpy(_price , price);//写入数据
	}
private:
	char _name[20];//车名
	char _price[20];//价格
};
void test4()
{
	car Byd_q;//定义出对象Byd_q
	car Byd_s;//定义出对象Byd_s
	Byd_q.Init("比亚迪 秦" , "99800");//向对象中写入数据
	Byd_s.Init("比亚迪 宋" , "154800");//向对象中写入数据

	Byd_q.print();//调用对象的打印函数
	Byd_s.print();//调用对象的打印函数
}

结果如下
在这里插入图片描述
上面说了对象只有数据,而类的函数是共用的。那为啥类的不同对象调用同一个函数会有不一样的结果(注意:要保证对象中的数据不一样)

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

this指针的特性

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

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

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

相关文章

Linux的目录结构

在Linux世界里&#xff0c;一切皆文件硬件如显卡、cpu等都会映射成一个文件具体的目录结构/bin 是Binary的缩写&#xff0c;这个目录存放着最经常使用的命令 /sbin(/usr/sbin、/usr/local/sbin) s就是Super User的意思&#xff0c;这里存放的是系统管理员使用的系统管理程序 /h…

Elasticsearch扫盲篇

1. 什么是搜索&#xff1f; 在日常的工作和学习中&#xff0c;当我们说想找查询任何的信息的时候&#xff0c;可能第一时间会想到上百度或者谷歌去搜索一下。比如说找一部自己喜欢的电影&#xff0c;或者说找一本喜欢的书&#xff0c;或者找一条感兴趣的新闻。但是百度和谷歌不…

QML基础模型(Basic Model)

最基本的分离数据与显示的方法是使用Repeater元素。它被用于实例化一组元素项&#xff0c;并且很容易与一个用于填充用户界面的定位器相结合。 最基本的实现举例&#xff0c;repeater元素用于实现子元素的标号。每个子元素都拥有一个可以访问的属性index&#xff0c;用于区分不…

第11章 项目人力资源管理

文章目录 项目人力资源管理 过程11.2.1 编制项目人力资源计划的工具与技术 375&#xff08;1&#xff09;层次结构图&#xff08;工作、组织、资源 分解结构&#xff09;&#xff08;2&#xff09;矩阵图&#xff08;责任分配矩阵&#xff0c;RAM&#xff09;&#xff08;3&…

KinectFusion中的ICP算法

投影数据关联-求匹配点 利用算法projective data association对前一帧和当前帧的&#xff08;Vertex、Normal&#xff09;进行匹配&#xff0c;算法如下&#xff1a; 在当前帧 i 的深度图像上的每一个像素 U并行计算&#xff1b;对于深度值大于0的像素&#xff0c;求该像素点…

从破解虫脑到攻克人脑:一条“永生之路”的新赛道?

从破解虫脑到攻克人脑&#xff1a;一条“永生之路”的新赛道&#xff1f; 首张果蝇大脑连接组&#xff1a;耗费十余年&#xff0c;重建三千神经元&#xff0c;超50万突触&#xff01; 论文地址 果蝇幼虫大脑的连接组。 所有脑神经元的形态学都经过了突触分辨率的电子显微镜成像…

聊天机器人开发实战--(微信小程序+SpringCloud+Pytorch+Flask)【后端部分】

文章目录 前言架构SpringCloud服务构建后台搭建Python服务调用 Python算法服务app 总结 前言 趁着五一有时间&#xff0c;先把大三下个学期的期末作业做了&#xff0c;把微信小程序和Java开发的一起做了。顺便把机器学习的也一起做了。所以的话&#xff0c;我们完整项目的技术…

如何用ChatGPT做书籍、报告、文件的读取与互动式问答?故事人物活起来

该场景对应的关键词库&#xff08;15个&#xff09;&#xff1a; 书籍、报告、文件、详细信息、查询、主题、作者、出版日期、出版社、问题、方面、原则、方法、概括、主要观点、解释。 注意&#xff1a; ChatGPT的知识库截止于2021年9月&#xff0c;对于更新的数据或最新出版…

系统化思维:大数中心原理与限制性选择原理。

系统化思维&#xff1a;大数中心原理与限制性选择原理TOC 许多人的思考特点都是混乱而复杂的&#xff0c;只有受过严格训练的人才能做到系统化思维。这里将讨论系统化思维的基础考量。 大数中心原理&#xff1a;大数中心原理是客观而真实的普遍存在&#xff0c;应用在思维上就…

ImageJ实践——拟合矩形选区探究(bounding rectangle),左侧优先法则

在上一篇ImageJ实践中ImageJ实践——测量大小/长短&#xff08;以细胞为例&#xff09;&#xff0c;我勾选了Set Measurements中的Bounding rectangle以测量细胞的长和宽&#xff08;实际上是拟合矩形的长短边&#xff09;&#xff0c;文末我也提出了自己的疑惑&#xff1a;拟合…

【GORM框架】模型定义超详解,确定不来看看?

博主简介&#xff1a;努力学习的大一在校计算机专业学生&#xff0c;热爱学习和创作。目前在学习和分享&#xff1a;数据结构、Go&#xff0c;Java等相关知识。博主主页&#xff1a; 是瑶瑶子啦所属专栏: GORM框架学习 近期目标&#xff1a;写好专栏的每一篇文章 目录 一、GORM…

Ansible自动化运维工具---Playbook

Ansible自动化运维工具--playbook 一、playbook1、playbook简介2、playbook应用场景3、yaml基本语法规则4、yaml支持数据结构 二、Inventory中的变量1、inventor变量参数 三、playbook实例1、编写httpd的playbook2、tasks列表和action3、条件测试4、迭代5、with_items模块6、te…

5.4.1树的存储结构 5.4.2树和森林的遍历

回忆一下树的逻辑结构&#xff1a; 双亲表示法&#xff08;顺序存储&#xff09; 如果增加一个结点M&#xff0c;L。毋须按照逻辑上的次序存储。 如果是删除元素&#xff1a; 方案一&#xff1a;比如说删除元素为G,设置其双亲结点为-1。 方案二&#xff1a; 把尾部的结点提上…

真题详解(对象)-软件设计(六十四)

真题详解(DNS)-软件设计&#xff08;六十三)https://blog.csdn.net/ke1ying/article/details/130448106 TCP和UCP都提供了_____能力。 端口寻址 解析&#xff1a; UDP是不可靠无连接协议&#xff0c;没有连接管理&#xff0c;没有流量控制&#xff0c;没有重试。 面向对象…

MySQL 常用命令

#--------------------------- #----cmd命令行连接MySql--------- cd C:\Program Files\MySQL\MySQL Server 5.5\bin # 启动mysql服务器 net start mysql # 关闭mysql服务器 net stop mysql # 进入mysql命令行 mysql -h localhost -u root -p 或mysql -u root -p #---------…

推荐算法实战项目:AutoRec模型原理以及案例实战(附完整 Python 代码)

本文要介绍的AutoRec模型是由澳大利亚国立大学在2015年提出的&#xff0c;它将自编码器(AutoEncoder)的思想与协同过滤(Collaborative Filter)的思想结合起来&#xff0c;提出了一种单隐层的简单神经网络推荐模型。 可以说这个模型的提出&#xff0c;拉开了使用深度学习解决推…

LVS - DR 模式集群搭建

VIPRIPweb1192.168.88.136httpdweb2192.168.88.139httpdLVS192.168.88.110192.168.88.144(DIP) 省略最后的共享存储&#xff0c;webserver内容不一致&#xff08;方便查看负载的效果&#xff09;&#xff0c;关闭防火墙&#xff0c;关闭se 1、配置web服务 web1和web2相同 y…

【文件描述符|重定向|缓冲区】

1 C语言文件操作的回顾 这块博主在讲解C语言时就已经做了很详细的讲解&#xff0c;这里就不详细讲了&#xff0c;直接给出代码。 写操作&#xff1a; #include<stdio.h> #include<stdlib.h> #include<errno.h> #define LOG "log.txt" …