
非静态成员函数只有一份,也就是说它会被多个同类的对象调用,那么问题来了 ----
当函数被调用的时候,它如何知道是哪一个对象调用了自己呢? ----
答案就是通过this指针来区分 --- 指针隐含在每一个非静态成员函数中,它会指向调用函数的对象 
说白了就是:谁调用了非静态成员函数,函数中包含的this指针就指向谁
1.我们创建好成员函数时, 编译器会自动帮我们创建好this指针(这个创建是我们看不见的),直接用就行
第二点的意思:
当有对象调用成员函数的时候,成员函数中的this指针就会指向对象,而这个this指针是可以作为函数返回值的(其解引用也一样),当我们返回this指针的解引用的时候 --- 由于指针指向的是调用函数的对象,所以此时我们返回的就是调用这个函数的对象 
1.解决名称冲突

当出现上面这种情况的时候 --- 指的是形参名称和成员变量名称重复
此时编译器会认为函数中所有和形参变量名相同的变量名所代表的变量都是形参变量
如何解决这个问题并实现我们本来的目的 --- 用形参变量来给成员变量赋值呢?
方法1:
养成好的编码习惯 --- 成员变量前面都加上一个 m_ 来表示这个是成员变量。
如 int m_age;
方法2:
利用this指针来区分形参变量和成员变量

首先我们可以知道this指向的是调用函数的对象,而访问对象中的成员变量/函数有两种方法:
一.在有对象名的时候,用对象名+点操作符+要访问的成员变量名/调用函数
二.有指向对象的指针的时候,用指针名+箭头操作符+要访问的成员变量名/调用函数
而在成员函数中我们刚好就有一个指向调用函数对象的指针
用这个指针来访问成员变量名,换一种访问方式就可以避免重名带来的选择问题
综上:
在成员函数中调用成员变量有两种方式:
一.直接用成员变量名来调用成员变量(在类中,成员变量相当于类这个范围内的全局变量),但是这样调用的话可能会出现成员变量名与函数形参名重复的问题
二.用函数中隐含的this指针(指向调用函数的对象)加箭头操作符来访问成员变量
2.用*this返回调用函数的对象本身
当我们调用函数的时候写的代码是:
函数名(传给函数的实参);
这行代码有两个作用:
一.告诉编译器我们要调用这个函数
二.这行代码会在函数调用完之后转换为函数返回值
- int add()
- {
- return 0;
- }
-
- int main()
- {
- add();
- }
add()告诉编译器我们要调用add这个函数,等函数调用完之后,这个add()就会转换为函数的返回值0
而函数返回值也可以是对象名(表示对象),而当函数返回值是对象的时候,这个返回继续访问返回的对象的成员变量/调用成员函数
这样的话上面的这行代码就可以被我们实现
我们只需要将
![]()
第一次调用函数的时候的返回值设为一个对象,那么就能够实现函数返回对象,对象继续调用函数的闭环
这句话的意思是 this 是指向调用函数的对象的指针,而 *this 就是这个对象
函数的返回方式有两种:
一.值返回
当返回类型与返回值的类型相同的时候我们进行的就是值返回
值返回的本质是拷贝,也就是说我们并不是直接将返回值返回,而是先将它拷贝一份后再返回
比如上面这一个函数:返回量是this指针指向的对象,返回类型就是对象对应的类,此时进行的就是值返回,而直返回的流程是:
1.获得返回值
2.创建一个与返回值相同类型的变量,并将返回值赋给这个变量(这行代码由编译器自动执行,我们看不见)
创建代码: 返回值的类型 变量名(这里的变量名就是我们在调用函数时的那行代码) = 返回值;
二.引用返回
引用返回的关键也是一行代码:
创建代码: 返回值的类型 &变量名(这里的变量名就是我们在调用函数时的那行代码) = 返回值; --- 这个就是引用的代码
用引用作为返回值的好处就是能够高效利用内存空间,而不是再创建一个变量后去拷贝
用引用返回的时候返回类型要写为 返回值的类型& -- 如下

值返回是创建新的变量开辟新的内存空间来装返回值,与返回值原来的内存空间没有关系
引用返回后的别名则依然指向返回值所处的内存空间
现在让我们回到本节的内容,我们要回到一个问题,当我们返回对象的时候为什么要用引用返回而不是用值返回?


原因就在上面的讲解中
1.如果我们用值返回的话
这行代码的意思就是:p2这个对象调用函数并返回一个新创建的对象p2',然后p2'这个新对象再调用函数返回另一个新对象p2''...
2.但是当我们用引用返回的时候,我们调用的始终是对象p2,只不过我们第一次是直接通过对象名调用函数,后面都是通过对象p2的别名来调用函数


1.通过类我们可以创建对象,同时也可以创建指向对象的指针
2.当指针指向NULL时,如上图,我们称这个指针为空指针
3.空指针也可以调用类中的成员函数,但是要注意这个成员函数中有没有用到this指针
如果成员函数中用到了this指针,而我们又用空指针+箭头操作符来访问这个成员函数的话,就会导致程序出错
(补充内容:在成员函数中当我们访问成员变量的时候我们的写法是直接写成员变量名
如左图,而在编译器实际执行代码的时候直接写成员变量名来访问的代码都会被转换为 this->成员变量名 这种形式
)
此时如果我们用空指针来调用成员函数的话,这个成员函数内的this指针就无法指向任何对象,因为没有对象给它指呀,这个时候:
![]()
这行代码就会出错,因为这行代码是通过this指针加箭头操作符的方式来访问指针指向的对象内的对应的成员函数,当指针连指向的对象都没有的时候又怎么能够找到对象内的成员变量呢?
能够通过指针加箭头操作符的方式来访问对象内的成员变量/调用成员函数的前提是:指针指向了一个对象

为了防止出现上面这种错误,我们可以在成员函数中加上一个判断,如上
在执行成员函数前先判断this指针是否为空
(不为空则this指针指向了一个对象,不违反前提,可以正常用this指针访问对象的成员变量;若为空,则直接用return;结束函数,保证不会出现上述这种无法访问的错误)

1.mutable : adj 可变的,会变的

如何将一个普通的成员函数转换为一个常函数?
答:在这个函数的括号后面加一个空格和一个cosnt关键字,如上图
在常函数中不可以修改成员属性,除非这个成员属性在声明的时候被multable关键字修饰
补充内容:this指针的本质是一个指针常量(常量指针是指向常量的指针),指针常量是指指针的指向不能够改变

在函数的括号后面加上 const 修饰的本质其实就是对编译器自动创建this指针的代码的更改
1.普通this指针的创建代码(编译器自动执行,我们看不见)
类名* const this = &调用函数的对象
2.而在函数的括号后面加上cosnt修饰为常函数的时候,this指针的创建代码就变为了:
cosnt 类名* const this = &调用函数的对象
此时this指针既是一个指针常量也是常量指针,其指向的内存空间不可更改,且内存空间中的数据也被修饰为了常数,也不可更改
1.在对象前加上一个cosnt修饰就是一个常对象了
2.常对象的成员属性是不可修改的(如果想要修改的话,被修改的成员属性必须是被multable所修饰的)
(被multable修饰的成员属性无论是在常函数中,还是在常对象中都可以被修改)
3.常对象只能够调用常函数