C++的类

news2024/11/24 7:34:09

文章目录

  • class定义类
    • 声明和定义不分离
    • 成员函数声明与定义的分离
  • 类的访问限定符
  • 类的实例化
  • 类对象的大小
  • this指针

引入:什么是类呢?
在C语言阶段,结构体成员只能是它的属性,这个结构体就相当于张三,小时候它只被赋予了名字,性别,家庭住址等属性,但是他没有去做某件事的能力,而C++中呢就相当于他长大了,就可以有骑车,跑步,和别人聊天的能力,这种既可以包含属性,又可以有某些行为的,我们就称它为类。
在C++中我们选择用关键字class来代替struct,当然struct也是可以继续用的

class定义类

类的定义有两种方式,一种是定义和声明都放在类体中,另一种是声明和定义分离分别放在.h和.cpp中

声明和定义不分离

在这里插入图片描述

成员函数声明与定义的分离

我们把结构体,类等放在头文件.h其中之一的目的就是为了方便我们去看,这个类的功能,那么当成员函数的声明与定义都放在头文件.h中时,未免就会造成头文件代码过多,不容易查看。此时我们就要让声明与定义分离,把成员函数的定义放到.cpp文件中,但是要加上类域,不然编译器就会分不清这个函数到底是普通函数还是成员函数。
例如上述代码成员函数定义在.cpp文件中就要这样写:
在这里插入图片描述

在这里插入图片描述
要指明类域且返回类型放在最前面。
如果成员函数是内联函数,那么它的声明与定义就不能分离,所以它的定义要定义在头文件中和声明放在一起。
成员函数直接定义在类里,默认相当于加上了inline,编译器就可能会把它当做内联函数处理。加不加inline只是为了提醒编译器,到底是不是内联函数取决于编译器自己。

类的访问限定符

为了安全起见,类引入了三种访问限定符分别为public(公有),private(私密),protected(受保护的)

#include <iostream>

using namespace std;

class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	//在类的内部是可以对私密变量进行访问的,
	//在外部不能对私密变量访问
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1, d2;
	//d1._year;成员变量_year是私密的不能在外部进行访问,只能在类中进行访问
	d1.Init(2004, 1, 01);
	d2.Init(2003, 1, 10);
	d1.Print();
	d2.Print();
	return 0;
}

public修饰的成员在类外可以被直接访问
protected和private修饰的成员在类外不能被直接访问
访问限定符的作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止,如果后面没有访问限定符,作用域就到 } 为止,即类结束。
class的默认访问权限为private,struct的默认访问权限为public(因为C++要兼容C)

类的实例化

#include <iostream>

using namespace std;

//类的实例化

class Person
{
public:
	void MyName()
	{
		cout << _name << endl;
	}
public:
	char* _name;//类的成员变量要加上符号与普通变量加以区分
	char* _sex;
	int _age;
};

int main()
{
	//Person.age = 20;未实例化不能使用类
	Person man;
	man.MyName();
	return 0;
}

其实就和之前的结构体一样你不能直接通过结构体类型去引用结构体的成员。
我们可以通过一个形象的例子来说明,这个类就像是一个房子的图纸,直接引用类的成员就相当于你要去这个图纸里主一样,你要先根据这个图纸把房子盖起来,然后才能去里面住。
这个图纸在还没有去建造的时候这个房子是不占空间的,你只有把房子盖起来了才会占据空间,同时你也可以根据这个图纸建造出很多个这样的房子,只不过这个房子所在的位置不同,类与建房子一样,可以实例出很多个类变量,且物理存储位置不同,在还没有对类进行实例化时,是不占空间的。

类对象的大小

类的大小是类中属性的大小还是方法的大小,还是属性和方法大小的总和呢?
先说结论类的大小只包括类中属性的大小,属性就是成员变量,不是方法。
我们还是拿房子举例,类中的成员变量就相当于是这个房子中的厨房,卧室,厕所等,这些属性当然每一个房子都会有,而成员方法就类似于篮球场,足球场等,可不可以放在家里呢?当然可以,但是未免也太占空间了,所以一般情况下小区的篮球场,足球场等是所有的居民共用的,所以这里的方法也是如此,它不存储在类中,而是放在一个公共区域内,供所有人使用。
类中成员变量的存储空间符合内存对齐。但是注意当这个类为空类时,就是没有成员变量的情况,默认占的内存空间为1,就相当于这个房子没有厨房,客厅,卧室等,但它仍然是一个房子是要占据空间的,是要让系统知道我这个房子是存在的。
此外结构体为什么要进行内存对齐?
假设你的系统在读取内存时一次读取八个字节,而一个值的存储恰好有一部分是存储在你所读的这八个字节中而另一部分是存储在下一次读取的八个字节中,那么对于这个数你就要读取两次,而如果是内存对齐呢这个数你只需要读一次就可以得到,具体内存对齐规则详见C语言三万字总结这篇文章。
那么又来了你也用我也用他也用这个健身房,怎么知道到底是谁再用呢?所以这就引出了另一个问题就是this指针。
this指针就像是在健身房人脸识别一样,每一个人都有一个脸,系统可以通过这张脸来识别你的身份。这张脸不需要你去设定,系统会自动帮你加上并识别。

#include <iostream>

using namespace std;

//this指针
class Date
{
public:
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1, d2;
	d1.Init(2004, 1, 01);
	d2.Init(2003, 1, 10);
	d1.Print();
	d2.Print();
	return 0;
}

上述初始化函数Init()是调用的同一个函数,是怎么确定这个此时是给哪个类对象进行初始化的呢?你可能会说这不是写了d1.,d2.了吗,肯定是对它的成员进行初始化呀,我们要追根溯源找到它的本质原因,其实函数调用的括号里有一个默认的this指针。
C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。

this指针

this指针是你调用类成员方法时自动添加上的。
你不能主动地去给这个方法加上形参this,或指定这个对象的地址。
**this指针是存放在栈帧里面的,本质和形参一样没有区别,**只不过是隐式传过去的。
this指针不是存放在对象里面的是存放于栈中的

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

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

相关文章

docker Mysql部署主从集群

目录 1 docker安装 2 docker mysql 安装配置 远程连接 2.0 配置 2.0.1 文件夹 配置 2.0.2 主库文件配置 my.cnf -> 主库 id 和 开启二进制日志 2.0.3 从库文件配置 -> 从库 id 2.1 mysql 主 -> 第一个端口号和从库不一样 2.1.1 docker run 主库 2.1.2 查看主…

Postman创建项目 对接口发起请求处理

查看本文之前 您需要理解了解 Postman 的几个简单工作区 如果还没有掌握 可以先查看我的文章 简单认识 Postman界面操作 那么 掌握之后 我们就可以正式来开启我们的接口测试 我们先选择 Collections 我们点上面这个加号 多拉一个项目出来 然后 我们选我们刚加号点出来的项目…

用LangChain构建大语言模型应用

用LangChain构建大语言模型应用 自 ChatGPT 发布以来&#xff0c;大型语言模型 (LLM) 广受欢迎。尽管您可能没有足够的资金和计算资源从头开始训练自己的大语言模型&#xff0c;但您仍然可以使用预训练的大语言模型来构建一些很酷的东西&#xff0c;例如&#xff1a; 可以根据…

01-权限提升-网站权限后台漏洞第三方获取

权限提升-网站权限后台漏洞第三方获取 本节课内容主要是权限提升的思路&#xff0c;不涉及技术 当前知识点在渗透流程中的点 前期-中期-后期对应知识关系 当前知识点在权限提升的重点 知识点顺序&#xff0c;理解思路&#xff0c;分类介绍等 当前知识点权限提升权限介绍 …

Java8

Java8 &#xff08;一&#xff09;、双列集合&#xff08;二&#xff09;、Map集合常用api&#xff08;三&#xff09;、Map集合的遍历方式&#xff08;四&#xff09;、HashMap&#xff08;五&#xff09;、LinkedHashMap&#xff08;六&#xff09;、TreeMap&#xff08;七&a…

Steve:AI创建视频和动画的在线工具

【产品介绍】 steve.ai是一款利用人工智能技术创建视频和动画的在线工具&#xff0c;可以让任何人在几分钟内把文字转换成吸引人的视频。核心功能是根据用户输入的文本&#xff0c;自动选择合适的素材、音乐、字幕和动效&#xff0c;生成高质量的视频。还提供了多种模板、风格和…

Photoshop如何使用滤镜之实例演示?

文章目录 0.引言1.将普通照片制作成油画效果2.使用液化滤镜修出完美身材3.用镜头光晕滤镜制作唯美的逆光人像4.用Camera Raw滤镜对偏色风景照进行调色 0.引言 因科研等多场景需要进行绘图处理&#xff0c;笔者对PS进行了学习&#xff0c;本文通过《Photoshop2021入门教程》及其…

Servlet 笔记

1. HTTP 协议 1.1 HTTP协议简介 超文本传输协议&#xff08;英文&#xff1a;HyperText Transfer Protocol&#xff0c;缩写&#xff1a;HTTP&#xff09;是一种用于分布式、协作式和超媒体信息系统的应用层协议。HTTP是万维网的数据通信的基础。 HTTP的发展是由蒂姆伯纳斯-…

etcd原理剖析一

为什么Kubernetes使用etcd&#xff1f; 首先我们来看服务高可用以及数据一致性。单副本存在单点故障&#xff0c;而多副本又引入数据一致性问题。 为了解决数据一致性问题&#xff0c;需要引入一个共识算法。例如Raft等。etcd选择了Raft&#xff0c;它将复杂的一致性问题分解…

Maven 笔记

1. Maven 的简介 1.1 简介 Maven 这个词可以翻译为"专家","内行"。作为Apache 组织中的一个开源项目&#xff0c;主要服务于基于java平台的项目构建&#xff0c;依赖管理和项目信息管理。 无论是小型的开源类库项目&#xff0c;还是大型的企业级应用&am…

Spring 5 笔记 - 入门与IOC

1. Spring 入门简介 Spring&#xff1a;轻量级、开源的JavaEE框架&#xff0c; 解决企业应用的复杂性。包括IOC和AOP两个核心部分。 IOC&#xff1a; 控制反转&#xff0c;把创建对象和对象之间的调用的过程都交给Spring 进行管理&#xff0c;使耦合度降低。 AOP&#xff1a…

Winform从入门到精通(38)—StatusStrip(史上最全)更新中

一、属性 1、Name 获取StatusStrip控件对象 2、AllowDrop 允许用户拖拽数据到控件上 3、AllowItemReorder 当用于按下alt键时,是否允许对项进行排列,如下图: 4、AllowMerge 5、Anchor 6、AutoSize 7、BackColor 设置StatusStrip的背景色 8、BackgroundImage 设置背…

R语言方差分析

R中的方差分析 介绍用于比较独立组的不同类型的方差分析&#xff0c;包括&#xff1a; 单因素方差分析&#xff1a;独立样本 t 检验的扩展&#xff0c;用于在存在两个以上组的情况下比较均值。这是方差分析检验的最简单情况&#xff0c;其中数据仅根据一个分组变量&#xff0…

垃圾回收器ZGC应用分析总结

目录 一、基本概述 二、基本关键技术知识总结 &#xff08;一&#xff09;三色标记法&#xff08;着色指针&#xff09; &#xff08;二&#xff09;读屏障 &#xff08;三&#xff09;多图映射 &#xff08;四&#xff09;简单场景说明ZGC并发 三、基本回收原理介绍 四…

PowerJob基本概念

本文来说下PowerJob的一些基本概念 文章目录 PowerJob概述PowerJob官网为什么选择PowerJob同类产品对比适用场景 PowerJob概述 PowerJob是新一代分布式任务调度与计算框架&#xff0c;支持CRON、API、固定频率、固定延迟等调度策略&#xff0c;提供工作流来编排任务解决依赖关系…

React框架第七课 语法基础课《第一课React你好世界》

React框架第七课 语法基础课《第一课React你好世界》 从这一课开始真正进入到React框架的基础语法学习&#xff0c;之前的前五课做个了解即可。 1 React框架的基本项目结构 ├── README.md 使用方法的文档 ├── node_modules 所有的依赖安装的目录 ├── package-lock.j…

[架构之路-181]-《软考-系统分析师》-19- 系统可靠性分析与设计 - 2-容错性: 软件容错技术

目录 前言&#xff1a; 1 9 . 4 软件容错技术 19.4.1 N 版本程序设计 1 . 与 通 常 软 件 开 发 过 程 的 区 别 2 . 其 他 需 要 注 意 的 问 题 19.4.2 恢复块方法 19.4.3 防卫式程序设计&#xff08;预防性设计&#xff09;》广泛使用 1 . 错误检测 2 . 破坏估计 …

【C++初阶】类与对象:6个默认成员函数-----构造函数和析构函数

我们在写代码的时候经常会忘记初始化和销毁&#xff0c;C的构造函数和析构函数就能避免这个问题。 默认成员函数&#xff1a;用户没有显式实现&#xff0c;编译器会生成的成员函数称为默认成员函数。 一.构造函数 A.概念 1.构造函数是一个特殊的成员函数&#xff1b; 2.名字与…

React框架的第八课 语法基础课《第二课React框架中的事件》

React框架的第八课 语法基础课《第二课React框架中的事件》 React中的事件是指通过React建立的应用程序中处理用户交互的响应。React事件处理程序只是在组件上调用的JavaScript函数&#xff0c;以响应某些类型的操作或事件&#xff0c;例如点击、触摸、滚动等。 React组件可以使…

【P3】HTTP 接口设计

一、简答 HTTP 接口设计 HTTP请求默认值&#xff1a; 配置 http 请求的默认值&#xff0c;比如协议、主机、端口 HTTP信息头管理器&#xff1a; 配置 http 请求的头部参数 HTTP请求&#xff1a; 用于和业务交互 查看结果树&#xff1a; 用于结果展示 二、准备工作 慕慕生…