C++--this指针

在研究this指针之前首先要明确两个概念:

1,面向过程编程和面向对象编程:就好比洗衣服,面向过程编程就是将洗衣服的每一个步骤都描述出来,而面向对象编程则是分别描述人要做哪些工作,洗衣机需要做哪些工作。C语言属于面向过程编程,C++属于面向对象编程,这也是这两种语言的根本区别之一。而面向对象编程也使得C++语言能够更好的应对规模更大,更复杂的项目。

2,类和对象:C++中的类对应C语言中的结构体,如果在C++环境中使用C中的结构体,则结构体自动升级成类。类和结构体的主要不同是结构体只能定义变量,而类中还可以定义方法(函数)。(由于类中可以同时定义变量和函数,难免会在函数中出现被定义的变量,这种情况下,在调用变量时可能会出现混淆,这是就需要在定义变量时加以区分,比如在变量名前面加上_。

#define _CRT_SECURE_NO_WARNINGS  
using namespace std;//调用C++中的全部库函数
struct student
{
	char _name[10]; //对变量的定义前面加上”_”是为了便于与类中定义的函数中的同名变量做区分
	int _age;
	int _id;
	void Init(const char* name, int age, int id)
	{
		strcpy(_name, name);//字符串不能直接赋值,需要借助strcpy函数
		_age = age;
		_id = id;
	}
	void print()
	{
		cout << _name << endl;
		cout << _age << endl;
		cout << _id << endl;
	}
};
int main()
{
	struct student s1;//兼容C的写法
	student s2;//C++中的写法
	s1.Init("张三", 18, 1);
	s2.Init("李四", 19, 2);//调用类s1,s2中的Init函数(和结构体一样,调用内容时用.)
	s1.print();
	s2.print();
	return 0;
}

3,封装:为什么要有封装。考虑一个汽车自动驾驶系统,需要有检测路况的系统,控制油箱的系统,导航的系统等等,为了汽车平稳运行,需要各个系统之间互相配合。但是,不同的系统需要处理的数据类型不同,如果将全部的数据都共享的话,会降低效率,甚至在系统运行出问题时可能会因为访问的数据出错而发生事故。因此,C++将某一个类中专门由这个类所需要使用和处理的数据定义为这个类私有的,只有这个类可以使用这些数据,这些数据不会到类的外面给其它类添麻烦。这就是封装。C++中的封装可以理解成是更严格的管理,C中的不封装则是自由发挥。(如果数据被封装了,但我仍然想处理数据,没有问题,可以在类中定义公有的函数,这些函数会调用这些数据。直接调用这些函数就可以间接的使用这些数据)。

总结起来就是封装达到的目的就是让你看的给你看,不让你看的不给你看。封装了但没有完全封装。

注:class和struct的一点重要区别就是,没有专门声明时,struct默认是公有,而class默认是私有。

class student
{
private: //这些数据本来是私有的,但是主函数可以通过调用Init和print函数来使用这些数据
	char _name[10];
	int _age;
	int _id;
public:
	void Init(const char* name, int age, int id) //Init函数需要传参,print函数却不需要,因为Init函数需要人为的赋值,需要外部的数据,而print函数只需要类中自带的那几个数据即可,因此不需要传参
	{
		strcpy(_name, name); 
		_age = age;
		_id = id;
	}
	void print()
	{
		cout << _name << endl;
		cout << _age << endl;
		cout << _id << endl;
	}
};
int main()
{
	struct student s1; 
	student s2; 
	s1.Init("张三", 18, 1);
	s2.Init("李四", 19, 2); 
	s1.print();
	s2.print();
	return 0;
}

4,类对象的存储方式:类对象中既有变量,又有函数。在调用类时,对于类中的变量,不同的调用中变量的值也大概率不同,因此类中理应该为变量留出空间来存储。但是对于类中的函数而言,只要调用这个类,这些函数无论如何都是相同的,只是其中的变量不同(参考上面的代码),那么当一个类创建多个对象时,相同的函数就会拷贝许多次,浪费空间。因此,对于类对象中的函数,将其存在了公共代码区。因此,对于类对象的大小,就是其中成员变量的大小之和,按照结构体内存对其的方式来存储。而当类中没有变量,只有函数,或者连函数都没有时,这种类称为空类,编译器给空类一个字节来标识这种类。

5,类的实例化:用类来创建对象的过程,成为类的实例化。可以这样理解,类就是图纸,而对象就是用图纸盖起的楼。(类更像是一种指导思想,在内存中,类不占用空间,只有当通过类创建了一个具体的对象之后,这个被创建的对象才会在内存中占用一块空间)

在介绍完上面的几个概念之后,就可以结合C++语言来分析可能遇到的问题,并可以理解this指针出现的必要性。

this指针:当我在主函数中利用类来创建出不同的对象,在引用对象中的函数时,一些函数可以传参,让编译器得以区分不同的函数。(因为对象中的函数不是分别存储的,而是存储在一个公共代码区,当不同的对象都去公共代码区调用同一个函数时,如何区分就成了问题)在这样的背景下,出现了this指针。

当我在类中定义一个函数时,编译器会自动在函数中定义一个形参变量,即this指针。而在对象中需要调用该函数时,又会在对象中自动加入一个参数,即该函数所属于的对象的地址。这样,通过this指针指向该函数所属对象的地址,类中存储在公共代码区的相应函数,就可以准确的找到需要调用该函数的对象,不会造成混淆。(引入指针以实现精准定向,而方便之处正在于这些事情都由编译器自动完成)

总结起来的话,每当我在类中定义一个函数时,都会通过this指针构建起该函数与不同的对象之间的联系,让公共代码区中的函数可以准确的找到需要使用它的对象。通过this指针,实现了那些本来存在公共代码区的函数好像就存在各个对象之中的效果,召之即来,挥之即去,不会在内存中占用额外的空间,但想要使用的时候随时可以使用。现在想来,这也正式指针本身的好处之一,只不过使用的环境不同了。

此外需要注意的是,我不但需要this指针来调用函数,对象中的变量实际上也需要this指针来调用。因为this指针实际上就是各个对象的地址,那么想调用存储在对象中的变量自然也就相当于用this指针来调用。

实际上,this指针就相当于类中每一个函数中的额外的一个参数,只不过不需要人为干预,编译器自动完成。

同时,this指针不能被改变(显而易见,改变了还玩啥)。

由于this指针本质上是形参,因此它存在栈中。

using namespace std;//调用C++中的全部库函数
class Date
{
public:
	//void Init(Date* const this, int year, int month, int day)
	void Init(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
		this->_year = year;
		this->_month = month;
		this->_day = day;
	}
	//void Print(Date* const this)
	void Print()//这里会定义一个this指针作为形参(Date* this),相应的,在下面的Date d1中的d1.print中也会有一个实参,即d1的地址,这样当我在主函数中调用d1中的Print函数时,形参this指针就直接可以指向d1的地址,这样就可以按照d1中的数据等打印出我想要的结果。
	{
		//this = nullptr;
		cout << _year << "-" << _month << "-" << _day << endl;
		// 一般情况,我们都不会像下面这样显示写
		cout << this->_year << "-" << this->_month << "-" << this->_day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1;
	d1.Init(2022, 1, 15);// d1.Init(&d1, 2022, 1, 15);
	d1.Print();          // d1.Print(&d1);
	Date d2;
	d2.Init(2022, 1, 16); // d2.Init(&d2, 2022, 1, 16);
	d2.Print();           // d2.Print(&d2);
	/*const int* p1 = nullptr;
	int* p2 = nullptr;
	p1 = p2;
	p2 = p1;*/
	return 0;
}

从今天开始总结C++的内容,希望开学之前能有进步,为开学后的三个月争取到一个良好的局面。都说最开始的十几节课最难,中间的20节课学的最爽,希望自己能把简单的部分留给开学后的艰难时光。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值