C++ 类和对象(1)

news2024/11/15 18:40:40

大纲
在这里插入图片描述

初步认识类和对象

c语言是面向过程的 关注的是过程 分析出求问题的步骤 通过调用函数逐步解决
c++是基于面向对象的 关注的是对象 将一件事情拆分成不同的对象 靠对象之间的交互完成
举个栗子
在这里插入图片描述

把大象关进冰箱。
面向过程的分析过程:
第一步:把冰箱门打开;
第二步:将大象放进冰箱;
第三步:把冰箱门关闭;
面向对象的分析过程:
第一步:分析动作是由那些实体发出的;
人 ,冰箱,大象
第二步:定义主体,为其增加属性和功能;
人,人需要有打开关闭冰箱,及将大象放入冰箱的功能;
冰箱,冰箱需要具有能开门和关门的属性;
大象,大象需要具有能够进入冰箱的功能
面向过程关注点在 开门 把大象装进去 关门 这三个过程中
面向对象 关注的是人 冰箱 大象 这三个类对象之间的关系

类的引入

在c语言中 结构体只能定义变量 但是在c++中 结构体不仅可以定义变量 还可以定义函数
比如

struct test
{
	int a = 10;
	int Add(int x, int y)
	{
		return x + y;
	}
};

上面使用结构体定义类 在C++中一般用class来定义

类的定义

class 为定义类的关键字

class Test
{
	//...
};

Test 为类的名字(自定义)
类中的元素称为类的成员
类中的变量称为类的属性或者成员变量
类中的函数称为类的函数或者类的方法

类的定义的两种方式

1.类的定义和声明全部方在类体中。

//test.cpp文件
class Test
{
	void Init()
	{
		//实现...
	}


	char _name;
	int _id;
	int _age;
};

2.声明放在头文件中、定义放在源文件中

//test.h文件
//声明
class Test
{
	void Init();

	char _name;
	int _id;
	int _age;
};
//test.cpp
//定义
#include "test.h"
void Test::Init()
{
	//实现...
}

一般更建议使用第二种方法

类的访问限定符

在这里插入图片描述
public 修饰的成员在类外面可以直接被访问
protected 和private修饰的成员在类外面不能直接被访问
访问权限作用域从该限定符出现的位置到下一个访问限定符出现的位置为止
如果后面没有访问限定符 作用域到}就结束了
class的默认权限是private struct默认是public
访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

class Test
{
public:
	void Init()
	{
		//实现...
	}

private:
	char _name;
	int _id;
	int _age;
};

类的作用域

类定义了一个新的作用域 类的所有成员都在类的作用域中 在类外面定义成员时 需要使用作用域限定符指明成员属于哪一个类
比如

class Test
{
public:
	void Init();

private:
	char _name;
	int _id;
	int _age;
};
//这里需要说明Init属于Test类
void Test::Init()
{
	cout << _name << endl;
}

类的实例化

用类创建对象称为类的实例化
类只是一个模型一样的东西 限定了类有哪些成员 定义出一个类并没有分配实际的存储空间
一个类可以实例化多个对象 对象将占用实际的空间来存储类的成员变量
类和对象的关系是一对多的 就好比现实生活中用图纸造房子 可以用一个图纸造n个房子 图纸就是类 房子就是对象
在这里插入图片描述

class Test
{
public:
	void Init();

private:
	char* _name;
	int _id;
	int _age;
};

void test()
{
	Test t1;
	Test t2;
	Test t3;
	Test t4;
	Test t5;
}

t1 t2 t3 t4 t5 都是实例化对象

类对象模型

类对象的大小

一个类中既有成员变量 又有成员函数 那么类的大小应该如何计算 解决这个问题之前 先看一下类对象在内存中的存储方式

类对象的存储方式

用类定义对象时 系统会为每个对象分配存储空间 如果一个类即包含成员变量和成员函数 需要分别为他们分配空间
在这里插入图片描述
这样分配空间太奢侈了 c++会只给成员变量分配空间 成员函数放在公共代码段
在这里插入图片描述
通过几个例子进行验证

#include<iostream>
using namespace std;
class Test
{
public:
	int Add(int x, int y)
	{
		return x + y;
	}

	int _a;
	int _b;
};
int main()
{
	cout << sizeof(Test) << endl;
	return 0;
}

上面程序的结果是8 成员函数的大小并没有计算

class Test2
{
	void fun()
	{

	}
};
int main()
{
	cout << sizeof(Test2) << endl;
	return 0;
}

一个类中只有成员函数时 大小为1

class Test3
{

};
int main()
{
	cout << sizeof(Test3) << endl;
	return 0;
}

类中什么也没有-空类 大小也是1

class Test
{
public:
	int Add(int x, int y)
	{
		return x + y;
	}

	char _a;
	int _b;
};

这个类的大小也是8 在类中也要注意内存对齐
结论:一个类的大小,就是成员变量之和不包含成员函数所占的空间,也要注意内存对齐
空类的大小比较特殊 编译器给空类一个字节来标识这个类的对象

this指针

#include<iostream>
using namespace std;
class Data
{
private:
	int _year;
	int _month;
	int _day;
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month<< "-" << _day << endl;
	}

};
int main()
{
	Data d1, d2;
	d1.Init(1,1,1);
	d2.Init(2023,10,20);
	d1.Print();
	d2.Print();
	return 0;
}

上面Data类中实例化两个对象d1和d2
d1调用成员函数Init的时候 该函数是如何知道调用的是d1对象 而不是d2对象呢?
在c++中引入this指针解决该问题: c++编译器给每个非静态的成员函数增加了一个隐藏的指针参数,让该指针指向当前对象 在函数体中 所有成员变量的操作都是由该指针去访问的。用户不需要自己传递,编译器自动完成
上面的代码可以看成这样
在这里插入图片描述
成员函数写成这样也是可以的

//void Init(Data* this,int year, int month, int day)//编译器处理成员函数隐藏的this指针 
void Init(int year, int month, int day)
	{
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
//void Print(Data* this)
void Print()
	{
		cout << this->_year << "-" << this->_month<< "-" << this->_day << endl;
	}

this指针的特征

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

通过下面的例子更好的认识this指针

#include<iostream>
using namespace std;
class A
{
public:
	void Print()
	{
		cout << "Print()" << endl;
	}
	void PrintA()
	{
		cout << _a << endl;
	}
private:
	int _a;
};
int main()
{
	A* p = nullptr;
	p->Print();
	p->PrintA();
	return 0;
}

可以看出p是一个空指针 当程序执行p->Print();时程序并不会崩溃 代码并没有对空指针p进行解引用,因为Print等成员函数地址并没有存到对象里面,成员函数的地址是存在公共代码段的。
当执行p->PrintA();时程序会崩溃 调用成员函数PrintA()没有问题 但是 PrintA()里面打印了成员变量_a;成员变量需要通过this指针引用 而此时this指针是空指针 对空指针进行解引用必然会导致程序崩溃

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

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

相关文章

优思学院|六西格玛的发展历程是怎样的?

在商业世界的星空中&#xff0c;有一颗璀璨的星星&#xff0c;它的名字叫做六西格玛。这颗星星不是一夜之间闪耀登场的&#xff0c;而是在商界的无尽深夜中&#xff0c;逐渐积累了耀眼的光芒。今天&#xff0c;我就来为大家介绍一下六西格玛的发展历程吧。 西格玛是啥&#xff…

nginx+apach+数据恢复+apk小练习hunan

这份练习来自项师兄,我们湖南警官的新一代大佬向专家,我就向师兄讨要了检材一份,然后自己练习一下在csdn写一下我的刷题经历,如有错误,还请指正,另外可以看向师兄的微信公众号 2023某省电子取证比武wp“ 参加比赛侥幸拿下第一,发一发复盘wp,大佬勿喷,如有错误请指出,…

R语言:因子分析 factor analysis

文章目录 因子分析数据集处理步骤主成分法做因子分析最大似然法做因子分析 因子分析 因子分析的用途与主成分分析类似&#xff0c;它也是一种降维方法。由于因子往往比主成分更易得到解释&#xff0c;故因子分析比主成分分析更容易成功&#xff0c;从而有更广泛的应用。 从方法…

Mac文件对比同步工具 Beyond Compare 4.4.7

Beyond Compare 4 是一款强大的文件和文件夹比较工具。它提供了一个直观的界面&#xff0c;使您可以快速比较和同步文件和文件夹。 Beyond Compare 4 具有许多有用的功能&#xff0c;包括比较和合并文件、文件夹和压缩文件&#xff0c;以及同步文件和文件夹。它支持各种类型的文…

万圣节海外网红营销:助力品牌赢得消费者的心

万圣节&#xff0c;源自古代凯尔特文化&#xff0c;如今已成为一个全球性的节庆。它不仅是一个传统的庆祝活动&#xff0c;还是商业和品牌推广的黄金机会。在当今数字时代&#xff0c;社交媒体和网红文化已经成为品牌推广的重要渠道。万圣节为品牌提供了一个独特的机会&#xf…

点进来看看要如何在Telegram上找到目标群组

Telegram作为目前除了WhatsApp之外&#xff0c;在苹果应用商店市场第二高下载量的社交媒体平台是我们出海企业不可以错过的资源。而且就在日前海外科技媒体TechCrunch爆料称&#xff0c;Telegram正与腾讯展开合作&#xff0c;有望将Telegram打造为一个类似微信的“超级应用生态…

java 使用poi读取excel内浮动图片

注意&#xff1a;仅读取到xls中的浮动图片&#xff0c;嵌入图片此方法读取不到 1、引入poi依赖 <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.17</version></dependency><depen…

C++11包装器

文章目录 1.当前程序的问题2.包装器的引入2.1包装器的定义2.2包装器的使用2.3包装器的出现对于2.1问题的解决 3.包装器的应用3.1C98写法3.2C11写法count()的用法下标运算符operator[ ]lambda表达式的另一种用法C11写法 1.当前程序的问题 template<class T, class K> K u…

MSC应用新进展

2023年9月23日&#xff0c;第四届中国干细胞与再生医学协同创新平台大会正式发布了我国首个人源干细胞国家标准《生物样本库多能干细胞管理技术规范》(GB/T42466-2023)&#xff0c;标志着我国在干细胞样本库管理上有了标准技术支撑&#xff0c;对于推动我国干细胞研究和应用的规…

React之Redux详解

一、Redux 1、是什么 React是用于构建用户界面的&#xff0c;帮助我们解决渲染DOM的过程 而在整个应用中会存在很多个组件&#xff0c;每个组件的state是由自身进行管理&#xff0c;包括组件定义自身的state、组件之间的通信通过props传递、使用Context实现数据共享 如果让…

【QT开发笔记-基础篇】| 第四章 事件QEvent | 4.8 绘图事件

本节对应的视频讲解&#xff1a;B_站_链_接 【QT开发笔记-基础篇】 第4章 事件 4.8 绘图事件(1) 本章要实现的整体效果如下&#xff1a; QEvent::Paint ​ 当窗口/控件需要重绘时&#xff0c;触发该事件&#xff0c;它对应的子类是 QPaintEvent 本节通过一个向 QLabel 上绘制…

“揭秘!如何通过京东商品详情接口轻松获取海量精准商品信息!“

京东商品详情接口可以通过HTTP GET请求获取商品详情信息。 请求参数包括num_iid&#xff0c;表示JD商品ID。 请求示例&#xff1a; GET /jd/item_get/?num_iid10335871600 HTTP/1.1 Host: api-vx.Taobaoapi2014.cn Connection: close Accept-Encoding: gzip 点击获取…

决策树深度探索: 从基础构建到机器学习应用

机器学习 第六课 决策树 概述决策树的基本概念决策树的应用决策树的基本构建节点 (Node)分支 (Branch)决策树的构造过程 信息增益熵 (Entropy)条件熵 (Conditional Entropy)信息增益 (Information Gain) 信息熵计算计算数据集的熵计算在给定属性条件下的熵计算信增益 (Informat…

深入剖析Java类加载过程:探寻类加载器的奥秘

摘要: 一个java文件从被加载到被卸载这个生命过程&#xff0c;总共要经历4个阶段&#xff1a; 加载->链接&#xff08;验证准备解析&#xff09;->初始化&#xff08;使用前的准备&#xff09;->使用->卸载 其中类加载过程包括加载、验证、准备、解析和初始化五个阶…

如何使用Abaqus import进行预应力跌落仿真

跌落测试除了单次跌落外&#xff0c;根据不同的标准需求&#xff0c;还有多次跌落或者预应力跌落&#xff0c;上次我们进行了单次跌落在Abaqus中的实现过程&#xff0c;今天我们使用Abaqus Import功能&#xff0c;进行卡扣的预应力跌落。 首先进行卡扣的装配仿真&#xff0c;在…

Note——time

time import import datetime import timeDefinition of time from 1970-01-01 00:00:00 UTC Coordinated Universal Time as the float format of ‘seconds’ For example use structured time lists [ year,month,day,hours,minutes,seconds…] 表示从1970-01-01 00:00:…

当苹果铅笔不能工作时,不一定都是苹果铅笔的问题!苹果铅笔不工作时如何修复

你的苹果铅笔没有按预期工作,可能有几个原因;大多数都有相当简单的修复方法。苹果铅笔的故障排除技巧在两代配件中基本相同。 本文中的信息适用于兼容iPad上的苹果铅笔(第二代)和苹果铅笔(第一代)。 检查蓄电池 苹果铅笔的电池必须充电才能工作。要检查iPad上的电池状…

云表:为什么要使用低代码开发?低代码选择指南

随着信息技术的不断发展&#xff0c;我们进入了一个数字化的时代。在这个时代&#xff0c;IT技术已经成为推动全球信息化浪潮的重要力量。然而&#xff0c;随着应用程序开发技术的不断发展&#xff0c;开发效率并没有像摩尔定律一样快速提升&#xff0c;反而成为了瓶颈。因此&a…

Django实现音乐网站 (21)

使用Python Django框架做一个音乐网站&#xff0c; 本篇音乐播放器功能完善及原有功能修改。 目录 播放列表修改 视图修改 删除、清空播放器 设置路由 视图处理 修改加载播放器脚本 模板修改 脚本设置 清空功能实现 删除列表音乐 播放列表无数据处理 视图修改 播放…