C++中的this指针和python中的self
在C++中,对象可以通过this指针来访问自己的地址,this指针是所有成员函数的隐含参数。当通过对象调用一个成员函数时,实际上是将这个对象的地址隐式地赋给了这个成员函数的this参数。
在python中,类中的方法的第一个参数永远都是self,这个参数表示调用这个方法的对象本身。通过对象调用方法时,隐式地将这个对象传给了调用方法的第一个参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 #include <iostream> #include <string> using namespace std;class Test { protected : string name; public : Test (string name){ this ->name = name; }; void ShowThis () { cout << "this指针的地址为:" << this << endl; }; void ShowName () { cout << this ->name << endl; }; Test& ReturnThis () { return *this ; }; }; int main () { Test test1 ("test1" ) ; Test test2 ("test2" ) ; cout << "test1所在的地址为:" << &test1 << endl; test1.ShowThis (); cout << "test2所在的地址为:" << &test2 << endl; test2.ShowThis (); Test& test3 = test1.ReturnThis (); cout << "test3所在的地址为:" << &test3 << endl; test3.ShowThis (); return 0 ; }
上面这段程序的输出为:
1 2 3 4 5 6 test1所在的地址为:0x7ffee4f653c0 this 指针的地址为:0x7ffee4f653c0 test2所在的地址为:0x7ffee4f65380 this 指针的地址为:0x7ffee4f65380 test3所在的地址为:0x7ffee4f653c0 this 指针的地址为:0x7ffee4f653c0
this指针的地址实际上就是这个对象的内存地址。在class定义时要用到对象本身时,此时还不知道变量名,this指针就可以指代类的对象自身。实际上python中类的self参数和this指针的作用基本完全一样:
1 2 3 4 5 6 7 8 9 10 11 class Test : def ShowSelf (self ): print ('self的值为:' , self) test1 = Test() test2 = Test() print ('test1的地址为:' , test1)test1.ShowSelf() print ('test2的地址为:' , test2)test2.ShowSelf()
上面这段程序的输出为:
1 2 3 4 test1的地址为: <__main__.Test object at 0x7f92447030a0 > self的值为: <__main__.Test object at 0x7f92447030a0 > test2的地址为: <__main__.Test object at 0x7f92447035e0 > self的值为: <__main__.Test object at 0x7f92447035e0 >
其实调用test1.ShowSelf()
和Test.ShowSelf(test1)
是没有区别的,在类中定义的方法默认为绑定方法,当通过对象调用时自动将该对象传给这个方法。
this指针和self都可以作为成员函数(类方法)的返回值,来返回当前调用这个函数的对象,比如在python中,一个上下文管理器的__enter__
方法的返回值就经常是self..
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class ContextManager : def __init__ (self ): print ('__init__方法在运行..' ) pass def __enter__ (self ): print ('进入了上下文管理器,并把__enter__方法的返回值给了as后的对象' ) return self def __exit__ (self, exc_type, exc_value, traceback ): print ('离开上下文管理器' ) pass def FunctionA (self ): print ('这个函数可以做些事情..' ) with ContextManager() as manager_a: manager_a.FunctionA()
输出为:
1 2 3 4 __init__方法在运行.. 进入了上下文管理器,并把__enter__方法的返回值给了as 后的对象 这个函数可以做些事情.. 离开上下文管理器