【C++】常方法+常对象
引言
前一节类的编译流程中简单介绍了this指针的类型,但没说为什么是这种定义方式。this指针的原型就是
类名* const this
,其实也就是为什么*的右边需要加个const,原因很简单:害怕程序员修改this指针的值,比如说:置空this = NULL; 这种操作对代码的后续执行是致命的。
(一)this指针+const
看了引言的小伙伴就很疑惑,明明都已经说过了this加const的情况,那为何还有const可加??
这是之前讲过的栗子:
1 | int a = 10; |
可以看到上面的p就相当于对象中的那个this指针的类型(依赖于对象),而cp就是我所谓的this指针+const了。很明显,并不重复。
C++中也为this指针提供了这种定义方式:(常方法)
返回值 方法名(形参列表)const;
()后面的const修饰的就是对应方法的第一个参数this指针,形式如下:const 类名* const this
,这里的左const就是我们在()后面加的const,右const是编译器在编译时期加的。
(二)常对象
有一句话叫做:常对象只能调用常方法
。上面已经讲述了常方法,那么这句话的意思也大概能够参透了。
这句话意味着:
- 常对象只能调用常方法;
- 普通对象可以调用所有方法;
下面我举个栗子解释下为什么是这样:
你能看出这段代码有什么问题吗??
1 |
|
分析:
- 先对p1分析:p1是一个Person类型的
普通对象
,调用常方法GetAge()
,编译器在编译阶段将该语句编译成GetAge(&p1);
,使用const Person const 类型的this指针指向p1的地址(Person类型),能力缩小,这是完全可行的。那么GetName()也自然可行,编译成功
。 - p2分析:p2的地址类型(const Person),在调用常方法
GetAge()
,编译期间被改写成GetAge(&p2)
,此时使用const Person const this指针指向p2,未对p2的产生影响,可行,编译成功
。但是在调用GetName()时,此时的this指针是Person* const
类型,而p2的地址(const Person),this保存p2的地址扩大了p2的能力,编译不通过
。*所以常对象只能调用常方法
(三)this指针的传递方式
this指针的调用跟调用约定相关。
(1)thiscall调用约定
thiscall仅仅应用于C++成员方法。
1 | lea ecx,[p1] ;将p1地址给ecx寄存器 |
(2)__cdecl调用约定
结论:__cdecl 比 thiscall 多了一次push和pop
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 code-016!