类和对象
C++对象模型和this指针
成员变量和成员函数的存储
C++中的成员变量和成员函数是分开存储的,只有非静态成员变量才属于类的对象上
Person 的对象p只有 m_Age的大小也就是4个字节。
this指针:
在之前的笔记中写过, 每个非静态成员变量只诞生一份实例,也就是说多个同类对象共用一块代码,那么问题来了,这一块代码是如何区分到底是哪个对象调用了自己的?
那么C++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用成员函数所属的对象。
this指针特性:
this指针是隐含每一个非静态成员函数内的一个指针
this指针不需要定义,直接使用即可
用途:
1.当行参和成员变量同名时,可以用this来区分。
上述例子中运行后会提示错误,这个错误就是因为age并不清楚哪个是成员变量哪个是参数传入的。
那就可以用this来区分一下。
在类的非静态成员函数中返回对象本身,可使用return *this
此时的运行结果是10+15=25,那如果我想要多加几次,可不可以直接:
这样肯定是不行,从语法来说就不对因为我们返回值是void,但是我们最终目的是多加几次,应该如何做呢?
如果我们让这个函数执行结果return的是p2本身,执行一次后就保存在p2了,是否就可以多次执行了
这个时候代码就不报错了,结果就变成了35了。当然依次类推,由于返回的是本身。所以如果我们这样加结果是多少呢?
后面再跟一个参数是p2的addAge,结果应该是70,因为前面p2年龄已经是35了,又传入了35加起来就是70了。
如果上面的返回值不是引用了,而是值,那么结果就会变为25,因为每次 addAge
都返回一个临时对象,并且每次调用都在新的临时对象上进行,因此这些操作都不会影响 p2
本身。
p2
的 age
在第一次调用后变为 25,之后的操作不再对 p2
本身产生影响。
这被称为是链式编程思维。
空指针访问成员函数
这里我们运行后程序会中断,原因在于showPersonAge()
这个函数身上。因为在
其实默认是有一个this->的
但是因为p是个空指针,所以会找不到这个数据,这当然会出错。
为了程序不断掉,我们可以这样做
加一个空指针的判断。
const修饰成员函数
常函数:
- 加上const修饰的函数称之为常函数
- 常函数不能修改成员属性(只读)
- 成员属性声明时加上关键字mutable后,在常函数中依然可以修改
const修饰后,我们就无法对m_A进行修改了。
我们怎么理解呢?
其实原函数也可以写为
每个成员函数都有一个this指针,this指针的本质就是指针常量,指针的指向是不可修改的。如果你在函数内部对this指针赋值,会报错,因为它是const的其实对于本例this等价于Person * const this。那如果想要this指向的值都不可修改就要在Person前面再加上const,就变成了:
这个const其实就是void showPerson() const。其本质修饰的就是this指针指向的值。
同样,我们想要在常函数中也可以修改这个值的话。就加上mutable关键字
常对象:
- 加上const修饰的对象称为常对象
- 常对象只能调用常函数
由于const修饰了p,m_B并不是const修饰的,所以这里也会报错。
但是
接下来我们在Person类中加上一个空的函数
使用静态修饰的对象p来调用,同样也会报错,因为常对象只能调用常函数,由于普通成员函数可以修改属性值,但是常函数不能修改值,如果允许我们这样做就会发生冲突了。