C++——类和对象(1)

news2024/11/20 14:33:35

1. 类

        我们之前提及过C语言是面向过程的语言,其解决问题的方式是关注问题过程,然后逐步解决。而C++是面向对象编程,聚焦于对象,依靠多个对象之间的交互关系解决问题。而类这个概念的引入则是面向对象的最深刻体现。

1.1 C++中的结构体

        C++兼容C,所以C++的结构体完全涵盖了C语言中结构体的语法形式。除此之外,C++结构体也做出了一些改进,如定义结构体变量不再一定需要struct关键字,不过最大的变化还是体现在结构体内可以定义函数了。

        在结构体内定义的函数可以直接使用结构体中的成员变量,在调用成员函数时可以直接使用成员访问的方式就行调用,函数中的成员变量则会自动被替换为调用结构体变量对应的结构体变量。

struct Stack {
	//C++的结构体内既可以定义变量,也可以定义函数
	//变量
	int* _arr;
	int _capacity;
	int _top;
	//函数
	void Init(int capacity = 4)
	{
		_arr = (int*)malloc(sizeof(int) * capacity);
		if (_arr == nullptr)
		{
			perror("malloc fail");
			return;
		}
		_capacity = capacity;
		_top = 0;
	}
};
int main()
{
	//定义结构体变量可以不加struct
	struct Stack st1;
	Stack st2;
	//调用成员函数
	st1.Init();
	st2.Init(8);
}

        需要注意的是成员变量的命名,尽量加入一些标识使得可以很容易分辨出是一个成员变量,以防在成员函数中调用产生分不清的情况。类的成员变量命名也要注意这一点。 

1.2 C++的类

        但是在C++中我们一般使用类来替代结构体,类的关键字为class。

1.2.1 类的定义

1.2.1.1 声明和定义全部放在类体中

        声明和定义同时放在类体中,这种方式比较简便,就像C语言阶段的声明定义不分离一样。

class Date
{
	int _year;
	int _month;
	int _day;
	void Show()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}
};
1.2.1.2 声明放在类的头文件,定义放在类的实现文件

        这种方法类似于C语言中的声明和变量分离,比较规整并且便于合作开发。

        这种方法需要注意类的作用域,即需要 类名::成员名 来指明成员所属的类域。

date.h

#pragma once
class Date
{
	int _year;
	int _month;
	int _day;

	void Show();
};

date.cpp

#include"date.h"
void Date::Show()
{
	cout << _year << '-' << _month << '-' << _day << endl;
}

1.2.2 类的访问限定符

1.2.2.1 封装

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

        封装指的是将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互。在C++中可以借助访问限定符,来控制哪些成员或方法可以在类外部使用,从而实现封装的特性。

1.2.2.2 访问限定符

        C++的访问限定符有三个:public(公有),protected(保护),private(私有)。这三个访问限定符只有public修饰的成员支持在类外被访问,而protected和private是不可以的。

        访问限定符在C++中的形式是访问限定符带一个冒号。其限定范围是自符号起到下一个访问限定符或类结束为止。

        class成员的默认访问权限是private,struct成员的默认访问权限是public。

struct Stack {
	int* _arr;
	int _capacity;
	int _top;
	
	void Init(int capacity = 4)
	{
		_arr = (int*)malloc(sizeof(int) * capacity);
		if (_arr == nullptr)
		{
			perror("malloc fail");
			return;
		}
		_capacity = capacity;
		_top = 0;
	}
private:
	void Show()
	{}
};
class Date
{
	int _year;
	int _month;
	int _day;

public:
	void Init(int year = 2000, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Show()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}
};

int main()
{
	struct Stack st1;
	//struct默认访问权限是public
	st1.Init();
	int a = st1._capacity;
	//st1.Show();//error

	Date d1;
	//class默认访问权限是private
	//d1._year = 2024; //error
	d1.Init();
	d1.Show(); 
}

1.2.3 类的实例化

        类和结构体在一定程度上是相似的。在定义结构体或类的时候只是限定了有哪些成员,类似于给出图纸,但此时并没有在内存中分配空间。直到我们创建结构体变量或类对象,这时候才会在内存中开辟空间,我们才能正常访问使用。这一步就叫做类的实例化。

class Date
{
	int _year;
	int _month;
	int _day;

public:
	void Init(int year = 2000, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Show()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}
};

int main()
{
	//Date.Init(); //error 没有实例化

	Date d1;
	d1.Init();
}

1.2.4 类的大小

        类的大小计算方式与结构体相同。类中的成员函数不会存放在对象开辟的空间中,而是统一放在代码段中。所以类的大小只与成员变量有关而与成员函数无关。当类中没有成员函数时,编译器中会为这个空类对象分配一个字节的空间作为占位。

class C1
{
	int a;
	char c;
	double d;
	void func()
	{}
};
class C2
{
	void func()
	{}
};
class C3
{};

int main()
{
	cout << sizeof(C1) << endl; //16
	cout << sizeof(C2) << endl; //1
	cout << sizeof(C3) << endl; //1
}

1.3 this指针

        在了解了这么多后有一个问题,在调用成员函数时,我们并没有传递对象的相关信息,函数凭什么知道我们调用的对象是d1而不是d2呢?这是因为this指针发挥了作用。

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

        我们可以通过观察汇编代码发现这个隐藏的this指针传参。

class Date
{
	int _year;
	int _month;
	int _day;

public:
	//void Init(Date* const this, int year = 2000, int month = 1, int day = 1)
	void Init(int year = 2000, int month = 1, int day = 1)	
	{
		this->_year = year;
		_month = month;
		_day = day;
	}
	//void Show(Date* const this)
	void Show()
	{
		cout << _year << '-' << _month << '-' << _day << endl;
	}
};
int main()
{
	Date d1;
	d1.Init(2024, 2, 25);
	d1.Show();
}

        我们对this指针进行总结:

①this指针的类型是 类类型* const,这说明在函数成员内不可以修改this,但是修改通过this解引用的值。

②this指针只能在成员函数内使用。

③对象中并不储存this指针,在成员函数调用时将对象的地址作为实参传递给成员函数的this形参。

④this指针真实存在,但是传参是由编译器自动完成的,我们不可以在实参和形参位置显式写出this指针的传递。

⑤我们可以在成员函数内部使用this指针。this作为参数,存储在栈中。

class C
{
public:
	int _a;

	void func()
	{
		cout << "func()" << endl; //没有使用this指针,所以没有空指针解引用,不报错
		//cout << _a << endl; //error 实际上是this->_a,this是空指针,所以报错
	}
};
int main()
{
	C c1;
	C* pc = nullptr;
	pc->func(); //-> 不解引用,而是将pc作为参数传给this,this接收参数,值为nullptr
	(*pc).func(); //. 不解引用,也是将pc传给this指针,this接收参数,值为nullptr
}

        在成员函数调用时,->或.两个操作符并不进行解引用,而是表示将传给this指针的对象是谁,所以在主函数中并未报错,在成员函数中访问成员变量时才会对this解引用。

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

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

相关文章

二叉树的增删查改

本节复习二叉树的增删查改&#xff0c; 二叉树的知识相对于前面的循序表&#xff0c; 链表&#xff0c; 以及栈和队列都要多一些。 同时二叉树的增删查改理解起来相对来说要困难一些。 本节来好好复习一下二叉树的增删查改。 目录 准备文件 创建结构体蓝图 二叉树的前序遍历…

【数据分享】2001-2022年我国省市县镇四级的逐日平均降水量数据(免费获取\excel\shp格式)

降水数据是我们在各项研究中最常用的气象指标之一&#xff01;之前我们给大家分享过来源于国家青藏高原科学数据中心发布的1961—2022年全国范围的逐日降水栅格数据&#xff08;可查看之前的文章获悉详情&#xff09;&#xff01; 本次我们分享的是2001-2002年我国省市县镇四个…

【中科院计算所】WSDM 2024冠军方案:基于大模型进行多文档问答

作者&#xff1a;李一鸣 张兆 中科院计算所 会话式多文档问答旨在根据检索到的文档以及上下文对话来回答特定问题。 在本文中&#xff0c;我们介绍了 WSDM Cup 2024 中“对话式多文档 QA”挑战赛的获胜方法&#xff0c;该方法利用了大型语言模型 (LLM) 卓越的自然语言理解和生…

Pyhton的组合数据类型

归纳编程学习的感悟&#xff0c; 记录奋斗路上的点滴&#xff0c; 希望能帮到一样刻苦的你&#xff01; 如有不足欢迎指正&#xff01; 共同学习交流&#xff01; &#x1f30e;欢迎各位→点赞 &#x1f44d; 收藏⭐ 留言​&#x1f4dd; 生命对某些人来说是美丽的&#xff0c…

二分查找讲解

关于我为什么要写单独开一篇文章写二分,实际上那么多困难的算法,比如线段树,并查集等等都没有难倒我,我最近却被二分难倒了,而且是两次,两次在赛场上做不出来二分的应用题,于是我决定写一篇二分查找的算法总结.刚接触算法的时候本来是要写一篇的,但后面因为各种原因搁置了,现在…

lv20 QT主窗口

熟悉创建主窗口项目 1 QAction 2 主窗口 菜单栏&#xff1a;fileMenu menuBar()->addMenu(tr("&File")); 工具栏&#xff1a;fileToolBar addToolBar(tr("File")); 浮动窗&#xff1a;QDockWidget *dockWidget new QDockWidget(tr("Dock W…

云上攻防-云服务篇弹性计算服务器云数据库实例元数据控制角色AK控制台接管

知识点: 1、云服务-弹性计算服务器-元数据&SSRF&AK 2、云服务-云数据库-外部连接&权限提升 章节点&#xff1a; 云场景攻防&#xff1a;公有云&#xff0c;私有云&#xff0c;混合云&#xff0c;虚拟化集群&#xff0c;云桌面等 云厂商攻防&#xff1a;阿里云&am…

Pytorch学习 day01(Jupyter安装

Jupyter 安装过程中遇到的问题&#xff1a; Anaconda的base环境会自动安装Jupyter&#xff0c;但是如果我们要在其他环境中安装Jupyter&#xff0c;就需要注意&#xff0c;该环境的python版本不能高于3.11&#xff0c;且用以下代码安装&#xff1a; conda install nb_conda_…

深度学习 精选笔记(8)梯度消失和梯度爆炸

学习参考&#xff1a; 动手学深度学习2.0Deep-Learning-with-TensorFlow-bookpytorchlightning ①如有冒犯、请联系侵删。 ②已写完的笔记文章会不定时一直修订修改(删、改、增)&#xff0c;以达到集多方教程的精华于一文的目的。 ③非常推荐上面&#xff08;学习参考&#x…

微信小程序 vs 公众号商城:亿发解密线上业务的最佳选择之道

在拓展线上业务的道路上&#xff0c;搭建线上商城成为企业首要选择。然而&#xff0c;在选择小程序商城和公众号商城时&#xff0c;很多企业陷入了两者之间的纠结。本文将深入解答小程序商城和公众号商城的概念、区别&#xff0c;并为您提供明智的选择建议。 一、小程序商城和公…

Flutter开发之Slider

Flutter开发之Slider 本文是关于介绍Slider相关属性的含义。 class SliderThemeData {/// slider轨道的高度 final double? trackHeight; /// 滑块滑过的轨道颜色 final Color? activeTrackColor; /// 滑块未滑过的轨道颜色 final Color? inactiveTrackColor; /// 滑块滑过…

多人同时导出 Excel 干崩服务器?我们来实现一个排队导出功能!

考虑到数据库数据日渐增多&#xff0c;导出会有全量数据的导出&#xff0c;多人同时导出可以会对服务性能造成影响&#xff0c;导出涉及到mysql查询的io操作&#xff0c;还涉及文件输入、输出流的io操作&#xff0c;所以对服务器的性能会影响的比较大&#xff1b; 结合以上原因…

李沐动手学习深度学习——3.2练习

以下是个人理解&#xff0c;希望进行讨论求解。 练习 1. 如果我们将权重初始化为零&#xff0c;会发生什么。算法仍然有效吗&#xff1f; 根据SGD算法公式如上&#xff0c;第一次迭代的值可知w只与b相关&#xff0c;而对于b的迭代更新&#xff0c;只是与b的初始值相关&#x…

什么是物联网?

今天这篇文章写的相关内容就是带领大家了解什么是物联网&#xff0c;之前写的文章大多都是一些物联网的未来&#xff0c;行业的解决方案等&#xff1b;话不多说开始进入正题吧! 物联网(IoT)是一个包罗万象的术语&#xff0c;指的是越来越多的电子产品&#xff0c;它们不是传统的…

【2022 J1】乘方

本主又双叒叕来更新了&#xff0c;一圈三连不用说了吧&#x1f601; 本题是J组第二轮的题&#xff1a; 题目描述 小文同学刚刚接触了信息学竞赛&#xff0c;有一天她遇到了这样一个题&#xff1a;给定正整数 a 和 b&#xff0c;求 &#xfffd;&#xfffd;ab 的值是多少。 …

Java优先级队列--堆

目录 1. 优先级队列 1.1 概念 2.优先级队列的模拟实现 2.1 堆的概念 2.2 堆的存储方式 2.3 堆的创建 2.3.1 堆向下调整 2.3.2 堆的创建 2.3.3 建堆的时间复杂度 2.4 堆的插入与删除 2.4.1 堆的插入 2.4.2 堆的删除 2.5 用堆模拟实现优先级队列 3.常用接口介绍 3…

Windows下使用C++调用海康威视SDK获取实时视频流进行检测

目录 准备海康威视的SDK官网下载下载后解压 Vs 2022创建项目创建32位的环境 将相关文件复制到工程目录下工程配置海康威视SDK配置包含目录配置库目录将dll文件添加到环境中在附加依赖项添加如下内容 工程配置OpenCV配置工程配置包含目录配置库目录 测试 准备海康威视的SDK 官网…

深入理解Linux线程(LWP):概念、结构与实现机制(1)

&#x1f3ac;慕斯主页&#xff1a;修仙—别有洞天 ♈️今日夜电波&#xff1a;会いたい—Naomile 1:12━━━━━━️&#x1f49f;──────── 4:59 &#x1f504; ◀️ ⏸ ▶️ ☰ &a…

JavaScript | 拼客JavaScript的P211-循环精灵图 精灵图及个人手敲代码分享

拼客JavaScript的P211-循环精灵图 JavaScript前端课程-dom-bom-js-es6新语法-jQuery-数据可视化echarts黑马pink老师前端入门基础视频教程(500多集)持续 视频中的拼客老师使用的是淘宝首页的精灵图资源24-595图片 精灵图24-595 我还找到另一张大一点的精灵图&#xff0c;内容…

【力扣 - 杨辉三角】

题目描述 给定一个非负整数 numRows&#xff0c;生成「杨辉三角」的前 numRows 行。 示例 1: 输入: numRows 5 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] 示例 2: 输入: numRows 1 输出: [[1]] 提示: 1 < numRows < 30 方法一&#xff1a;数学 思路…