this指针我并不陌生,学过java的都知道,this在java中也经常出现。今天我专门研究了一下C++中的this指针。
http://www.cnblogs.com/hnrainll/archive/2011/05/20/2051939.html
this指针指向的就是调用该方法的对象,对this的解引用*this就是调用该方法的对象。
this指针的含义及其用法:
1. this指针是一个隐含于每一个成员函数中的特殊指针。它指向正在被该成员函数操作的那个对象。
2. 当对一个对象调用成员函数时,编译程序先将对象的地址赋给this指针,然后调用成员函数,每次成员函数存取数据成员时,由隐含使用this指针。(参加下面的例子)
3. 当一个成员函数被调用时,自动向它传递一个隐含的参数,该参数是一个指向这个成员函数所在的对象的指针。
4. 在C++中,this指针被隐含地声明为: X *const this,这意味着不能给this 指针赋值;
在X类的const成员函数中,this指针的类型为:const X* const, 这说明this指针所指向的这种对象是不可修改的(即不能对这种对象的数据成员进行赋值操作);
5. 由于this并不是一个常规变量,所以,不能取得this的地址。
6. 在以下场景中,经常需要显式引用this指针
(1)为实现对象的链式引用
(2)为避免对同一对象进行赋值操作
(3)在实现一些数据结构时,如list.
一个对象的this指针并不是对象本身的一部分,不会影响 sizeof(对象)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过 this进行。
你认为它可以顺利执行吗?
class A { public: void Hello(conststd::string& name) { std::cout <<"hello " << name; } }; int main(int argc, char** argv) { A* pa = NULL; //!! pa->Hello("world"); return 0; }
试试的确可以顺利运行输出helloworld,奇怪吗?其实并不奇怪,根据C++对象模型,类的非虚方法并不会存在于对象内存布局中,实际上编译器是把Hello方法转化成了类似这样的全局函数:
void A_Hello_xxx(A * const this, const std::string& name) { std::cout << “hello“ << name; }
对象指针其实是作为第一个参数被隐式传递的,pa->Hello(“world”)实际上是调用的A_Hello_xxx(pa,“world”),而恰好A_Hello_xxx内部没有使用pa,所以这段代码得以顺利运行。
对于类成员函数而言,并不是一个对象对应一个单独的成员函数体,而是此类的所有对象共用这个成员函数体。当程序被编译之后,此成员函数地址即已确定。而成员函数之所以能把属于此类的各个对象的数据区别开, 就是靠这个this指针。函数体内所有对类数据成员的访问,都会被转化为this->数据成员的方式。
http://blog.csdn.net/starlee/article/details/2062586
给出了如下的例子:
class CNullPointCall { public: static void Test1(); void Test2(); void Test3(int iTest); void Test4(); private: static int m_iStatic; int m_iTest; }; int CNullPointCall::m_iStatic = 0; void CNullPointCall::Test1() { cout << m_iStatic << endl; } void CNullPointCall::Test2() { cout << "Very Cool!" << endl; } void CNullPointCall::Test3(int iTest) { cout << iTest << endl; } void CNullPointCall::Test4() { cout << m_iTest << endl; } CNullPointCall *pNull = NULL; // 没错,就是给指针赋值为空 pNull->Test1(); // call 1 pNull->Test2(); // call 2 pNull->Test3(13); // call 3 pNull->Test4(); // call 4
“除了call 4那行代码以外,其余3个类成员函数的调用都是成功的,都能正确的输出结果,而且包含这3行代码的程序能非常好的运行。
经过细心的比较就可以发现,call 4那行代码跟其他3行代码的本质区别:类CNullPointCall的成员函数中用到了this指针。对于上面的例子来说,this的值也就是pNull的值。也就是说this的值为NULL。而Test1()是静态函数,编译器不会给它传递this指针,所以call 1那行代码可以正确调用(这里相当于CNullPointCall::Test1());对于Test2()和Test3()两个成员函数,虽然编译器会 给这两个函数传递this指针,但是它们并没有通过this指针来访问类的成员变量,因此call
2和call 3两行代码可以正确调用;而对于成员函数Test4()要访问类的成员变量,因此要使用this指针,这个时候发现this指针的值为NULL,就会造成程序的崩溃。 ”