C++ 类和对象(初篇)

news2024/11/18 12:26:48

类的引入

C语言中,结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。

而为了区分C和C++我们将结构体重新命名成class去定义

类的定义

标准格式:

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

注意:结构体不是函数,不管是C的struct还是C++的class 最后大括号完了都得加上“;”

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

类的两种定义方式:

声明和定义都在结构体中:

同一个.cpp文件下

#include <iostream>
using namespace std;
//. 声明和定义全部放在类体中
class Date
{
public:
	//结构体中的函数
	void Init(int year,int month ,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void ShowDate()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
public:
	//结构体中的变量
	int _year;//年
	int _month;
	int _day;

};
int main()
{
	Date dt;
	dt.Init(2024, 4, 1);
	dt.ShowDate();
	return 0;
}

声明在.h,定义在.cpp(常用):

.h声明 person

#include <iostream>
using namespace std;
//. 声明和定义全部放在类体中
class Date
{
public:
	//结构体中的函数
	void Init(int year, int month, int day);
	void ShowDate();
public:
	//结构体中的变量
	int _year;//年
	int _month;
	int _day;
};


.C++ person


#include "person.h"

//结构体中的函数
void Date::Init(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;
}
void Date::ShowDate()
{
	cout << _year << "-" << _month << "-" << _day << endl;
}


.C++ main
#include "person.h"

int main()
{
	Date dt;
	dt.Init(2024, 4, 1);
	dt.ShowDate();
	return 0;
}

为什么使用域作用限定符?

回答:当在不同文件中声明定义,可能会出现相同函数,但是又因为结构体和命名空间等的包装,就需要专门::去打开。

成员变量前加“_”

成员变量(结构体里的变量)和函数参数变量都为相同的时,无法区分,为了更明显表现在代码上各变量关系,常用“_”来表示成员变量

类的访问限定符及封装:

上图一个会报错一个不会报错,其中最关键的在于public。由此我们能看出这个结构体默认是不让你胡乱在结构体外修改他的结构体内的变量的。

我们并不希望结构体内的有些东西会被修改,例如成员变量。

访问限定符:

说明:

1. public修饰的成员在类外可以直接被访问

2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)

3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止

4. class的默认访问权限为private,struct为public(因为struct要兼容C)

封装:

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

面向对象的三大特性:封装、继承、多态

定义:封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行 交互。

本质:通过将我们想要保护的隐私东西用保险箱保护(封装)起来。

通过不同的保护容器来实现不同的效果,例如,可以公开的信息就用透明箱子等;

类的作用域

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

类的实例化

定义:用类类型创建对象的过程,称为类的实例化(由图纸->实物)

1.类只是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际内存空间来存储它

2.. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

简单理解:类只是给你设计了一个住宅区的建筑图纸,你可以用这份图纸在任何地方去建造住宅区,这个过程(给类申请空间)就叫做实例化过程;

//类--设计图纸
class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void ShowDate()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
public:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date dt;//类的实例化--开实际空间
	dt.Init(2024, 4, 1);
	dt.ShowDate();
	return 0;
}

类的对象大小的计算

结论:一个类的大小,实际就是该类中”成员变量”之和,当然也要进行内存对齐,注意空类的大小,空类比较特殊,编译器给了空类一个字节来唯一标识这个类

类的存储位置

注意:类里面函数运行的指令是存在代码段里,但是运行过程中的参数是存在栈里

结构体内存对齐规则:
1. 第一个成员在与结构体偏移量为0的地址处。

2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。 VS中默认的对齐数为8

3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。

4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是 所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

类成员函数this指针

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

this指针的特性:

1.this指针的类型:类类型* const

2. 只能在“成员函数”的内部使用

3.this指针是成员函数第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传递,不需要用户传递

4.this指针本质上其实是一个成员函数的形参,是对象调用成员函数时,将对象地址作为实参传递给this 形参。所以对象中不存储this指针。

this存在哪里?

1.栈,因为他是隐含形参

2.VS下,是通过ecx寄存器

空指针问题:

//测试空指针问题
class Date
{
public:
	void Init(int year, int month, int day)
	{
		cout << this << endl;
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
	void Show()
	{
		cout << this << endl;
		cout << "func()" << endl;
	}
public:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;

	d1.Init(1111, 11, 1);

	Date* ptr = nullptr;

	ptr->Show();		   //正常运行
	(*ptr).Show();          //正常运行
	ptr->Init(3333, 33, 3);//运行崩溃
	return 0;
}

重点:解引用使用时主要看我们所申请的这个对象里包不包括我们要调用的函数或者变量。

解读代码:

结构体的解引用不一定都是有效的,例如ptr->Init()这里进去后要修改_year的数据,此时ptr解引用后并无实际存储数据空间,只是单纯的申请了了一个地址空间。所以此时解引用后是无法进行操作的。

show函数他只进行显示地址等并没有数据的操作过程

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

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

相关文章

linux安装和使用Rancher

linux安装和使用Rancher Rancher介绍请看如下博客 arm架构安装Rancher并导入k8s集群解决Error: no objects passed to apply 华为云arm架构安装k8s(kubernetes) linux下安装Rancher Rancher部署监控k8s集群状态等,比Dashboard插件强大 提前安装好K8S 在master上执行#如果…

学习心得1

这时我第一次更学习心得&#xff01;不足的在评论区指教。 首先先来分享一下&#xff0c;刷一维数组题目的方法。 仔细读题&#xff0c;不会做的题目先完成输入输出。不要干等着着急&#xff0c;就跳到下一题。如果使用的时oj&#xff0c;那就没有题解但是使用洛谷、LeetCood…

【热门话题】计算机视觉入门:探索数字世界中的“视觉智能”

&#x1f308;个人主页: 鑫宝Code &#x1f525;热门专栏: 闲话杂谈&#xff5c; 炫酷HTML | JavaScript基础 ​&#x1f4ab;个人格言: "如无必要&#xff0c;勿增实体" 文章目录 计算机视觉入门&#xff1a;探索数字世界中的“视觉智能”摘要正文一、计算机视…

MATLAB——知识点备忘

最近在攻略ADC建模相关方面&#xff0c;由好多零碎的知识点&#xff0c;这里写个备忘录。 Matlab 判断一个数是否为整数 1. isinteger 函数 MATLAB中&#xff0c;可以使用 isinteger 函数来判断一个数是否为整数&#xff0c;例如&#xff1a;要判断x是否为整数可以采用以下代…

链式二叉树经典OJ题目(二)

目录 结构体及头文件&#xff1a; 1.二叉树的前序遍历 题目描述&#xff1a; 思路分析&#xff1a; 源码&#xff1a; 2.二叉树的翻转 题目描述&#xff1a; 思路分析&#xff1a; 源码&#xff1a; 3.另一颗子树 题目描述&#xff1a; 思路分析&#xff1a; 源码&…

蓝桥杯单片机真题实践篇

这里就不完全写思路过程代码什么的&#xff0c;这一篇文章就写我在训练真题中遇到的过程。 &#xff08;呜呜呜&#xff0c;时间不够辣&#xff0c;能做多少算多少吧....&#xff09; 十三届省赛题 问题1&#xff1a;数码管的数字消影不明显 &#xff08;参考&#xff1a;蓝…

Splunk Attack Range:一款针对Splunk安全的模拟测试环境创建工具

关于Splunk Attack Range Splunk Attack Range是一款针对Splunk安全的模拟测试环境创建工具&#xff0c;该工具完全开源&#xff0c;目前由Splunk威胁研究团队负责维护。 该工具能够帮助广大研究人员构建模拟攻击测试所用的本地或云端环境&#xff0c;并将数据转发至Splunk实例…

ARM架构学习笔记1-寄存器

ARM内部寄存器 有R0-R1516个寄存器 R0-R12通用目的寄存器Program status Register&#xff1a;程序状态寄存器 &#xff0c;用来保存某些状态的值保存:m3/m4架构保存在xPSR&#xff0c;coretex-A7架构保存在CPSR中XPSR是程序状态寄存器 MRS命令&#xff1a;表示Move to Regis…

Tuxera NTFS for Mac2023绿色免费版 免费的ntfs for mac 免费读写硬盘U盘工具

Tuxera NTFS 2023 Mac免费版是款适合Mac用户使用的磁盘读写工具。Tuxera NTFS 2023 Mac可以很好的帮助用户在Mac上打开、编辑、复制、移动或删除存储在Windows NTFS格式的USB驱动器上的文件。并且Tuxera NTFS 2023 Mac还可以无阻碍地使用各种文件系统磁盘&#xff0c;还能解决磁…

数据生成 | Matlab实现基于K-means和SVM的GMM高斯混合分布的数据生成

数据生成 | Matlab实现基于K-means和SVM的GMM高斯混合分布的数据生成 目录 数据生成 | Matlab实现基于K-means和SVM的GMM高斯混合分布的数据生成生成效果基本描述模型描述程序设计参考资料 生成效果 基本描述 1.Matlab实现基于K-means和SVM的GMM高斯混合分布的数据生成&#xf…

vivado 向 SVF 目标添加器件

向 SVF 目标添加器件 创建 SVF 目标后 &#xff0c; 可向其中添加器件以定义 SVF JTAG 器件链配置。 SVF JTAG 器件链配置应与目标硬件链相匹配 &#xff0c; 以 确保能正确执行 SVF 文件。 使用 Vivado IDE 单击“ ”按钮以向 SVF 链添加赛灵思器件或非赛灵思器件。…

法向量估计

法向量估计 1. 求解点P法向量的原理2. 法向量估计的证明3. 为什么求点P的法向量&#xff0c;需要使用以P为中心的邻域内的点&#xff1f;4. 法向量估计的应用和思考5. 权重法向量估计 1. 求解点P法向量的原理 已知有一组点 P ( p 1 , p 2 , p 3 , . . . , p n ) , p i ∈ R 3…

糖豆人打开失败或无法运行

一般就是网络不行&#xff0c;选择加速器加速就好了。 eg: (uu加速器) 一般直接点启动游戏就行。 如果提示找不到文件路径&#xff0c;或者说直接弹出steam的登录的话就是配置路径有问题。现在糖豆人已经不再steam平台了&#xff0c;应该是epic才对。 配置方法&#xff1a;…

普通人想要赚钱,就要坚持五个要点

最近都在努力搞钱&#xff0c;所以今天就围绕【持续赚钱】&#xff0c;分享一些心得体会。 普通人想要赚钱&#xff0c;就要坚持以下5点&#xff1a; 持续学习 持续破圈 持续行动 坚持长期利他 坚持长期主义 1、持续学习 要持续学习&#xff0c;做一个终身学习者。 只有保持空杯…

通用开发技能系列:Git

云原生学习路线导航页&#xff08;持续更新中&#xff09; 本文是 通用开发技能系列 文章&#xff0c;主要对编程通用技能Git进行学习 1.为什么使用版本控制系统 版本控制系统可以解决的问题 代码备份很重要版本控制很重要协同工作很重要责任追溯很重要 常见的版本控制系统 Gi…

【学习笔记】java项目—苍穹外卖day10

文章目录 苍穹外卖-day10课程内容1. Spring Task1.1 介绍1.2 cron表达式1.3 入门案例1.3.1 Spring Task使用步骤1.3.2 代码开发1.3.3 功能测试 2.订单状态定时处理2.1 需求分析2.2 代码开发2.3 功能测试 3. WebSocket3.1 介绍3.2 入门案例3.2.1 案例分析3.2.2 代码开发3.2.3 功…

Django环境搭建及测试

Django环境搭建及测试 一、安装 Python二、安装 Django三、终端命令创建 Django 项目四、运行 Django 项目五、访问 Django 网站 一、安装 Python 首先确保你的电脑上安装了 Python。 Python官网点击直达 官网下载后双击即可安装 第一个相当于快速安装&#xff0c;第二个则是…

【保姆级讲解如何计算机视觉入门】

&#x1f308;个人主页:程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

C++中的STL——vector类的基本使用

目录 vector介绍 vetor类定义 vector常见构造 vector类中的容量操作 size()函数与capacity()函数 resize()函数 reserve()函数 max_size()函数 vector类中的数据遍历操作 operator[]()与at()函数 vector类中的迭代器遍历 正向遍历begin()和end()迭代器——非const …

练习 22 Web [极客大挑战 2019]BuyFlag

php弱类型比较&#xff0c;注意Cookie值&#xff0c;php利用数组赋值进行绕过,科学计数法 很明显是弱类型比较&#xff0c;之前的练习题已经遇到过 构造password404adsffd&#xff0c;后面随便什么字母都行 然后 money100000000 然后在student这里卡了很久&#xff0c;post…