类和对象一

目录

1.类的引入

2.类的定义

3.访问限定符

4.类的作用域

5.类对象模型

6.类的大小


1.类的引入

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

C++兼容C语言,结构用法可以继续使用

同时sruct也升级成了类

struct Stack
{
	int* a;
	int top;
	int capacity;
};
int main()
{
	struct Stack s1;
	Stack s2;
	return 0;
}

我们可以用两种方式定义结构体,s1是C语言的。s2是C++的

上面那串的Stack是类名,有了类名就可以作下面的类型

还有一个成员函数,C语言的初始化都要放在外面去写,现在我们还可以在类里面写成员函数了,而且不用传这个参数了,成员变量它直接就能访问

struct Stack
{
	void Init()
	{
		a = nullptr;
		top = capacity = 0;
	}
	int* a;
	int top;
	int capacity;
};
int main()
{
	Stack s2;
	s2.Init();
	return 0;
}

还有比如说push我们也可以类似上面一样的写法

s2.Push(1);

2.类的定义

class className
{

};

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

那么class和struct有什么区别呢

class引入了访问限定符这一类的概念

3.访问限定符

访问限定符分为了三个1.public(公有)2.protected(保护)3.private(私有)

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

2.protected和private的成员在类外不能直接被访问

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

4.如果后面没有访问限定符,作用域就到}即类结束

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

class Stack
{
	void Init()
	{
		a = nullptr;
		top = capacity = 0;
	}
	void Push(int x)
	{
		if (top == capacity)
		{
			size_t newcapacity = capacity == 0?4:capacity * 2;
			a = (int*)realloc(a,sizeof(int) * newcapacity);
			capacity = newcapacity;
		}
		a[top++] = x;
	}
	int* a;
	int top;
	int capacity;
};
int main()
{
	Stack s2;
	s2.Init();
	s2.Push(1);
	return 0;
}

这里是无法被访问的,那么我们为什么要引入class呢

	cout << s2.a[s2.top] << endl;
	cout << s2.a[s2.top-1] << endl;

有人以为可以访问栈顶元素是可以这样子搞,但是它不知道是指向栈顶元素还是指向栈顶元素的下一个位置

实际上指向的是栈顶元素的下一个位置,所以C++就不希望别人这样随意的访问

class Stack
{
public:
	void Init()
	{
		a = nullptr;
		top = capacity = 0;
	}
	void Push(int x)
	{
		if (top == capacity)
		{
			size_t newcapacity = capacity == 0?4:capacity * 2;
			a = (int*)realloc(a,sizeof(int) * newcapacity);
			capacity = newcapacity;
		}
		a[top++] = x;
	}
	int Top()
	{
		return a[top - 1];
	}
private:
	int* a;
	int top;
	int capacity;
};
int main()
{
	Stack s2;
	s2.Init();
	s2.Push(1);
	cout << s2.Top() << endl;
	return 0;
}

这样子通过private和public的限定我们就能让你访问到我想让你访问到的和不想让你访问到的,比如说你想访问栈顶元素,我们在类里面通过操作来反馈给你就大大减少了出错的可能性了

但是我们上面一个public去掉就跑不动了,因为class默认是私有的

类里面不受访问限定符的限制,限制的是类外面的

类的两种定义方式

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

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

这里是.h文件里面的

class Stack
{
public:
	void Init();
	void Push(int x);
	int Top();
private:
	int* a;
	int top;
	int capacity;
};

这里是.cpp文件里面的

void Stack::Init()
{
	a = nullptr;
	top = capacity = 0;
};
void Stack::Push(int x)
{
	if (top == capacity)
	{
		size_t newcapacity = capacity == 0 ? 4 : capacity * 2;
		a = (int*)realloc(a, sizeof(int) * newcapacity);
		capacity = newcapacity;
	}
	a[top++] = x;
};
int Stack::Top()
{
	return a[top - 1];
};

这里加Stack::是为了区分全局函数和成员函数,还可以使用类域里面的成员变量和成员函数(编译器默认去全局域里面找)

注意:类里面没有向上查找这种说法,类是类域范围里面都可以使用的,你在上面使用一个变量,它会在类域这个范围内查找

这里我们引入一个日期类

class Date
{
public:
	void Init(int year, int month, int day)
	{
		year = year;
	month = month;
	day = day;
	}
private:
	int year;
	int month;
	int day;
};
int main()
{
	Date d;
	d.Init(2022, 7, 19);
}

这里就涉及到域搜索的知识,一个是局部域的year,一个是类域的year,局部优先,所以是自己赋值给自己,所以好区分我们通常可以这样子写

	int _year;
	int _month;
	int _day;

C++标准并没有这么写,看你的个人意愿,就形成了风格

4.类的作用域

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

这个我们在上面的内容也有间接提到,不做过多的解释

5.类对象模型

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

1.类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间类储存它;

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

我们解除私有,我们能不能这样访问

int main()
{
	Date::_year;
	Date._year;
}

这样是不行的,因为我们上面的年月日是声明不是定义,声明没有给它开空间不能访问

Date d;

这才是定义,定义开出来空间上面的空间就都开出来了我们就可以访问它了

而且我们不能直接去访问,因为是私有的,我们要通过间接的方式去访问

d._year=1;

这样是不行的

类就像一个图纸,我们只有建出来才是实体

6.类的大小

我们来看这个类的大小

cout << sizeof(Date) << endl;
cout << sizeof(d) << endl;

我们可以看见函数的大小是不包括在里面的,为什么呢

Date d1;
d1.Init(1,2,3);
Date d2;
d2.Init(4, 5, 6);

如果我们在每个对象中都存一个这样一个函数肯定是不划算的,就像是我们小区里面的公共空间这个小区里面都可以使用,但是像年月日就是自己房子里面的家具,自己使用

所以类里面的函数都存在公共代码区,所以每次使用的时候都会去这个区域里面使用

这一点我们通过汇编代码也可以得到证实 

我们看一下类中仅有成员函数和空类的大小

class A2
{
public:
	void f2(){}
};
class A3
{

};
int main()
{
	cout << sizeof(A2) << endl;
	cout << sizeof(A3) << endl;
}

有成员函数和没有成员函数是没有区别的,成员函数也不存在对象里面

这里涉及到占位的知识

C++对于这种只有成员函数和空类,分配1byte,不存储数据,只是占位

设想一下我们如果连一个byte位都不给它分配我们怎么区别,不定义过怎么证明这个对象存在

A2 a1;
A2 b1;
cout <<& a1 << endl;
cout << &b1 << endl;

类和对象的知识和指针一样都起到承上启下的作用,而且类和对象的知识也是很多的,学好了类和对象才好理解下面的STL知识等等,如果写的不好欢迎大家指出

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

AcWing 906. 区间分组

文章目录 前言代码思路 前言 前面两个都是右端点排序&#xff0c;这个我又是无脑右端点排序&#xff0c;直接 wa 了。哭。感觉反正做什么事情都不要太着急&#xff0c;心平气和地做还是比较好。没什么大不了的。考点统计 代码 #include<bits/stdc.h> using namespace …

用拉普拉斯变换的方差算法实现相机自动对焦

使用拉普拉斯变换的方差来计算图像的清晰度的主要原因是拉普拉斯算子可以有效检测图像的边缘和高频细节。图像的清晰度与边缘强度和高频分量的丰富程度密切相关,以下是更详细的解释: 1. 拉普拉斯算子的作用 拉普拉斯算子是一种二阶导数算子,定义为: 它可以在图像中检测快…

非文件形式的内存动态函数库调用接口

使用memfd的系统调用接口将动态库加载到proc虚拟文件系统&#xff0c;提供的fd为进程持有的句柄&#xff0c;通过dlopen的path指向此句柄&#xff0c;即可实现非文件系统加载动态链接库。 文章目录 一、memfd_create二、dl_open三、示例参考 一、memfd_create 接口名称int mem…

SpringBoot 开源停车场管理收费系统

一、下载项目文件 下载源码项目文件口令&#xff1a; 【前端小程序地址】(3.0)&#xff1a;伏脂火器白泽知洞座/~6f8d356LNL~:/【后台管理地址】(3.0)&#xff1a;伏脂火器仇恨篆洞座/~0f4a356Ks2~:/【岗亭端地址】(3.0)&#xff1a;动作火器智汇堂多好/~dd69356K6r~:/复制口令…

计算生成报价单小程序系统开发方案

计算生成报价单小程序报价系统&#xff0c;是根据商品品牌、类型、型号、规格、芯数、特性、颜色、分类进行选择不同的参数进行生成报价单&#xff0c;要求报价单支持生成图片、pdf、excel表格。 计算生成报价单小程序系统的主要功能模块有&#xff1a; 1、在线生成报价单&…

当 webclient 返回复杂json, 但是我只需要其中几个字段的解决方案

当 webclient 返回复杂json, 但是我只需要其中几个字段的解决方案: Spring 的 WebClient 使用 Jackson 作为默认的 JSON 序列化和反序列化工具&#xff0c;可以轻松将 JSON 映射为对象。

【C/C++】指针相关题目(个人笔记)

我们来详细分析这个C程序的执行流程&#xff0c;并预测它的输出结果。 首先&#xff0c;看一下程序的代码&#xff1a; #include <stdio.h>void main() {int a {1, 2, 3, 4};int *p;p &a;printf("%d ", *p);printf("%d\n", *--p); } 接下来&a…

在算网云平台云端在线部署stable diffusion (0基础小白超详细教程)

Stable Diffusion无疑是AIGC领域中的AI绘画利器&#xff0c;具有以下显著优势&#xff1a; 1、开源性质&#xff0c;支持本地部署 2、能够实现对图像生成过程的精确控制 虽然SD在使用上有很多的有点&#xff0c;但缺点也是不言而喻的&#xff0c;由于AI绘画的整个过程以及现…

初次使用uniapp编译到微信小程序编辑器页面空白,真机预览有内容

uniapp微信小程序页面结构 首页页面代码 微信小程序模拟器 模拟器页面为空白时查了下&#xff0c;有几个说是“Hbuilder编译的时候应该编译出来一个app.js文件 但是却编译出了App.js”&#xff0c;但是我的小程序结构没问题&#xff0c;并且真机预览没有问题 真机调试 根据defi…

【工业机器视觉】基于深度学习的仪表盘识读(读数识别)(1)

前言 本文旨在详述机器视觉技术在水表自动化读数领域的应用&#xff0c;具体聚焦于通过深度学习与传统图像处理方法相结合的方式&#xff0c;实现对仪表盘上字轮数字及指针位置的精准识别。在此基础上&#xff0c;通过对指针角度的分析进行初次读数校正&#xff0c;并利…

C语言数据结构作业

一、在堆区空间连续申请5个int类型大小空间&#xff0c;用来存放从终端输入的5个学生成绩&#xff0c;然后显示5个学生成绩。再将学生成绩升序排序&#xff0c;排序后&#xff0c;再次显示学生成绩。显示和排序分别用函数完成。 要求&#xff1a;用malloc和free完成。 二、课程…

C—指针初阶(2)

如果看完阁下满意的话&#xff0c;能否一键三连呢&#xff0c;我的动力就是大家的支持与肯定&#xff0c;冲&#xff01; 二级指针 我们先看概念以及作用&#xff1a;用来存放一级指针的地址的指针 先看例子&#xff0c;我们逐一分析 我们先分析上面那个“1” 标注那里&#x…

成立北京高途公益基金会,陈向东用爱点亮教育公益新征程

12月10日&#xff0c;北京高途公益基金会正式成立。本次成立仪式在京举办&#xff0c;以“用爱点亮”为主题&#xff0c;吸引了来自教育、公益慈善、媒体等领域的200多名嘉宾参加。 活动中&#xff0c;北京高途公益基金会与北京师范大学教育基金会签署了战略合作协议&#xff…

C# winfrom 窗体简单加载框实现详解

文章目录 前言一、为什么需要加载框&#xff1f;二、简单加载框的实现方式2.1 使用模态对话框作为加载框2.2 结合BackgroundWorker和加载框实现更好的效果2.3 加载动画 三、延伸内容3.1 自定义加载框样式3.2 使用第三方控件实现加载框 结束语优质源码分享 C# winfrom 窗体简单加…

第三十九篇——条件概率和贝叶斯公式:机器翻译是怎么工作的?

目录 一、背景介绍二、思路&方案三、过程1.思维导图2.文章中经典的句子理解3.学习之后对于投资市场的理解4.通过这篇文章结合我知道的东西我能想到什么&#xff1f; 四、总结五、升华 一、背景介绍 数学中的概率&#xff0c;看似和我们的生活没关系&#xff0c;其实它却是…

Leetcode 每日一题 202.快乐数

目录 题意 算法思路 过题图片 算法实现 代码解析 复杂度分析 题目链接 结论 题意 判断正整数 n 是不是快乐数。 快乐数定义&#xff1a; &#xff08;1&#xff09;每次将正整数替换为它每个位置上的数字的平方和。 &#xff08;2&#xff09;重复这个过程直到这个数…

CSS学习记录10

CSS图标 向HTML页面添加图标的最简单方法是使用图标库&#xff0c;例如Bootstrap。将指定的图标类的名称添加到任何行内HTML元素&#xff08;如<i> 或 <span>&#xff09;。下面的图标库中的所有图标都是可缩放矢量&#xff0c;可以使用CSS进行自定义&#xff08;…

1.3.4 输入输出技术

目录 接口的功能及分类主机与外设间的连接方式I/O接口的编址方式CPU与外设之间交换数据的方式 接口的功能及分类 输入/输出&#xff08;Input/Output, I/O&#xff09;系统是计算机与外界进行数据交换的通道。 I/O接口是连接主机和I/O设备的转换机构。由于I/O设备种类多样&…

Linux 权限及管理

目录 一、Linux权限 1、概念 2、超级用户和普通用户的相关操作 a. 添加用户&#xff0c;删除用户 b. 超级用户和普通用户的切换 c. sduo提权以及白名单设置 二、Linux权限管理 1、文件访问者的分类 2、文件访问类型和权限 a. 文件类型 b. 基本权限 3、文件权限值…

Linux网络测试指令

Ping Ping命令是一个网络工具&#xff0c;用于测试主机之间的可达性。它通过发送ICMP&#xff08;Internet Control Message Protocol&#xff09;回声请求消息到目标主机&#xff0c;并等待接收ICMP回声应答消息来判断目标是否可达以及测量往返时间。Ping命令对于诊断网络连接…