C++ this 指针 浅析

来源:互联网 发布:怎么看淘宝店家的地址 编辑:程序博客网 时间:2024/05/15 07:59

【摘要】

本文分三部分。第一部分this指针的的产生原因,即为了让不同对象调用同一函数时,通过this指针来对不同对象的地址加以区别实现函数共用。第二部分讲述this指针的使用,函数的返回值为对象本身或者函数的输入参数与成员变量相冲突时都需要this指针帮助实现。第三部分,讲述this指针几个常见的易混淆的问题。

【正文】

一. 为什么会有this

定义一个对象,系统要给该对象分配存储空间,如果该类包含了成员变量和成员函数,就要分别给变量和函数的代码分配存储空间。按正常思路,如果类定义了2个对象,那么就应该分别给这2个对象的变量和函数分配空间。事实并非如此,C++的编译系统只用了一段空间来存放在公共函数代码,在调用各个对象的成员函数时,都要调用这个公共的函数代码因此,每个对象的存储空间都只是该对象数据成员所占用的存储空间,而不包括成员函数代码所占有的空间,函数代码是存储在对象空间之外的。那么,问题来了,既然所有对象所调用的成员函数代码仅单独一分,那么成员函数是怎么知道当前调用自己的是哪一个对象呢?

  这时就诞生了this这个自引用的指针。每当创建一个对象时,系统就把this指针初始化为指向该对象,即this指针的值为当前调用成员函数的对象的起始地址。每当调用一个成员函数时,系统就把this指针作为一个隐含的参数传给该函数。不同的对象调用同一个成员函数时,C++编译器将根据成员函数的this指针所指向的对象来确定应该调用哪一个对象的数据成员。


二. this指针的使用

一种情况就是,在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this;另外一种情况是当参数与成员变量名相同时使用this指针,如this->num = num (不能写成num = num)。


三. this指针易混淆的几个问题

  • this指针只能在成员函数中使用。全局函数,静态函数都不能使用this。 成员函数默认第一个参数为 T* const this。

【例】

函数在形式上:

class A

{
...

int func(int p){ ... }

...

}

在编译器看来

class A

{

...

int func(A *const this,int p){ ... }

...

}

  • this在成员函数的开始前构造的,在成员的结束后清除。这个生命周期同任一个函数的参数是一样的,没有任何区别。当调用一个类的成员函数时,编译器将类的指针作为函数的this参数传递进去。

【例】

函数在形式上:

...

A a;

a.func( 10 );

...

在编译器看来

...
A a;

a.func( &a ,10 );

...

  • this 指针并不占用对象的内存空间。他与对象之间并不存在包含关系,只是当对象调用函数时,对象被this指向而已。
  • this 指针存放在何处?堆,栈,全局变量,还是其他?  
this 指针会因编译器不同,而放置的位置不同。可能是栈,也可能是寄存器,甚至全局变量。  
  • this 指针如何传递给类中函数的 ?绑定 ?还是在函数参数的首参数就是this指针,那么this指针又是如何找到 “类实例后函数” 的 ? ??????


this是通过函数的首参来传递的。this指针是在调用之前生成的。

类实例后的函数,没有这个说法。类在实例化时,只分配类中的变量空间,并没有为函数分配空间,类的函数在定义完成后,它就在那儿,不会跑的。   

  • this指针如何访问类中变量的?如果不是类,而是结构的话,那么,如何通过结构指针来访问结构中的变量呢?
在C++中,类和结构是只有一个区别的:类的成员默认是private,而结构是public。this是类的指针,如果换成结构,那this就是结构的指针了。   

  • 我们只有获得一个对象后,才能通过对象使用this指针,如果我们知道一个对象this指针的位置可以直接使用吗? 
this指针只有在成员函数中才有定义。因此,你获得一个对象后,也不能通过对象使用this指针。所以,我们也无法知道一个对象的this指针的位置(只有在成员函数里才有this指针的位置)。当然,在成员函数里,你是可以知道this指针的位置的(可以&this获得),也可以直接使用的。

  • 每个类编译后,是否创建一个类中函数表保存函数指针,以便用来调用函数?   

普通的类函数(不论是成员函数,还是静态函数),都不会创建一个函数表来保存函数指针的。只有虚函数才会被放到函数表中。但是,即使是虚函数,如果编译器能明确知道调用的是哪个函数,编译器就不会通过函数表中的指针来间接调用,而是会直接调用该函数。

0 0
原创粉丝点击