ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
[TOC] # 原理 通过上例我们知道,c++的数据和操作也是分开存储,并且每一个非内联成员函数(non-inline member function)只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码 那么问题是:这一块代码是如何区分那个对象调用自己的呢? ![](https://img.kancloud.cn/83/4e/834ea98f82abd2319706ac6f3f8634f5_363x166.png) c++通过提供特殊的对象指针,this指针,解决上述问题。This指针指向被调用的成员函数所属的对象。 c++规定,this指针是隐含在对象成员函数内的一种指针。当一个对象被创建后,它的每一个成员函数都含有一个系统自动生成的隐含指针this,用以保存这个对象的地址,也就是说虽然我们没有写上this指针,编译器在编译的时候也是会加上的。因此this也称为“指向本对象的指针”,this指针并不是对象的一部分,不会影响sizeof(对象)的结果。 this指针是C++实现封装的一种机制,它将对象和该对象调用的成员函数连接在一起,在外部看来,每一个对象都拥有自己的函数成员。一般情况下,并不写this,而是让系统进行默认设置。 > this指针永远指向当前对象。 成员函数通过this指针即可知道操作的是那个对象的数据。**This指针是一种隐含指针,它隐含于每个类的非静态成员函数中。**This指针无需定义,直接使用即可。 **注意:静态成员函数内部没有this指针,静态成员函数不能操作非静态成员变量。** # **c++编译器对普通成员函数的内部处理** ![](https://img.kancloud.cn/16/92/16922778de82e4a96bffe41524dc52e2_680x353.png) # this指针的使用 * 当形参和成员变量同名时,可用this指针来区分 * 在类的非静态成员函数中返回对象本身,可使用`return *this.` ~~~ class Person{ public: //1. 当形参名和成员变量名一样时,this指针可用来区分 Person(string name,int age){ //name = name; //age = age; //输出错误 this->name = name; this->age = age; } //2. 返回对象本身的引用 //重载赋值操作符 //其实也是两个参数,其中隐藏了一个this指针 Person PersonPlusPerson(Person& person){ string newname = this->name + person.name; int newage = this->age + person.age; Person newperson(newname, newage); return newperson; } void ShowPerson(){ cout << "Name:" << name << " Age:" << age << endl; } public: string name; int age; }; //3. 成员函数和全局函数(Perosn对象相加) Person PersonPlusPerson(Person& p1,Person& p2){ string newname = p1.name + p2.name; int newage = p1.age + p2.age; Person newperson(newname,newage); return newperson; } int main(){ Person person("John",100); person.ShowPerson(); cout << "---------" << endl; Person person1("John",20); Person person2("001", 10); //1.全局函数实现两个对象相加 Person person3 = PersonPlusPerson(person1, person2); person1.ShowPerson(); person2.ShowPerson(); person3.ShowPerson(); //2. 成员函数实现两个对象相加 Person person4 = person1.PersonPlusPerson(person2); person4.ShowPerson(); system("pause"); return EXIT_SUCCESS; } ~~~ # 常函数 * 用const修饰的成员函数时,const修饰this指针指向的内存区域,成员函数体内不可以修改本类中的任何普通成员变量, * 当成员变量类型符前用mutable修饰时例外。 ~~~ //const修饰成员函数 class Person{ public: Person(){ this->mAge = 0; this->mID = 0; } //在函数括号后面加上const,修饰成员变量不可修改,除了mutable变量 void sonmeOperate() const{ //this->mAge = 200; //mAge不可修改 this->mID = 10; } void ShowPerson(){ cout << "ID:" << mID << " mAge:" << mAge << endl; } private: int mAge; mutable int mID; }; int main(){ Person person; person.sonmeOperate(); person.ShowPerson(); system("pause"); return EXIT_SUCCESS; } ~~~ # 常对象 * 常对象只能调用const的成员函数 * 常对象可访问 const 或非 const 数据成员,不能修改,除非成员用mutable修饰 ~~~ class Person{ public: Person(){ this->mAge = 0; this->mID = 0; } void ChangePerson() const{ mAge = 100; mID = 100; } void ShowPerson(){ this->mAge = 1000; cout << "ID:" << this->mID << " Age:" << this->mAge << endl; } public: int mAge; mutable int mID; }; void test(){ const Person person; //1. 可访问数据成员 cout << "Age:" << person.mAge << endl; //person.mAge = 300; //不可修改 person.mID = 1001; //但是可以修改mutable修饰的成员变量 //2. 只能访问const修饰的函数 //person.ShowPerson(); person.ChangePerson(); } ~~~