博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
c++中的this指针
阅读量:4185 次
发布时间:2019-05-26

本文共 2754 字,大约阅读时间需要 9 分钟。

struct person{    char _name[20];    char _gender[3];    int _age;};void SetpersonInfo(person* p,char* name, char*gender, int age){    strcpy(p->_name, name);    strcpy(p->_gender, gender);    p->_age = age;}void Printperson(person* p){    cout << p->_name << "" << p->_gender << "" <
_age << endl;}

从上述c语言代码中我们可以看出,函数如果要操纵类对象,必须要将类对象的信息给进来,为了节省空间,传递了该对象的地址。

实际上,在c++类中的成员函数实现方式和上述类似,(非静态)成员函数也有一个隐藏的指针,指向了调用函数的对象本身。这个指针就叫做:this指针。

class person{public:    void SetpersonInfo(char* name,char*gender,int age)    {        strcpy(_name, name);        strcpy(_gender, gender);        _age = age;    }    void Printperson()    {        cout << _name << "" << _gender << "" << _age << endl;    }private:    char _name[20];    char _gender[3];    int _age;};int main(){    person s1,s2,s3;    s1.SetpersonInfo("哈哈", "男", 18);    s2.SetpersonInfo("嘿嘿", "女", 19);    s3.SetpersonInfo("吼吼", "男", 20);    s1.Printperson();    s2.Printperson();    s3.Printperson();    return 0;}

在上述代码中,我们用person类创建了三个对象s1,s2,s3,然后分别调用SetpersonInfo函数来设置每个对象里面的具体信息。

但是我们发现每个对象只用来保存数据信息,代码和数据分开来存储并且只存储了一份,从函数形式来看,SetpersonInfo函数只有一份(如下图所示)并且函数中没有区分不同对象的标志,为什么当s1调用函数时,函数就知道是s1调用而不是其他函数呢?

this指针

这就要引入c++中的下一个知识点–this指针

解答:(非静态)成员函数都有一个隐藏的指针,当调用函数时,该指针自动指向调用函数的对象,该指针存放的就是当前对象的地址,因此,编译器就知道是哪一个对象调用了函数。

this指针:

1.主要作用:

this指针:用来存放当前对象的地址

,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。

this指针是类的一个自动生成、自动隐藏的私有成员,它存在于类的非静态成员函数中,指向被调用函数所在的对象。

全局仅有一个this指针,当一个对象被创建时,this指针就存放指向对象数据的首地址。

2.如何使用:

(1)在类的非静态成员函数中返回类对象本身的时候,直接使用 return *this

(2)当参数与成员变量名相同时使用this指针,如this->n = n (不能写成n = n)

3.this指针特性:

  • this指针类型:类类型*const

  • 一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果

  • this作用域是在类的非静态成员函数内部

    -this指针是类的非静态成员函数的第一个默认隐含参数,编译器自动维护传递,类编写者不能显式传递

  • 只有在类的非静态成员函数中才能使用this指针,其他函数都不可以

4._thiscall调用约定:

  • _thiscall只能够用在类的成员函数上

  • 参数从右向左压栈

  • 如果参数确定,this指针通过ecx传递给被调用者;如果参数不确定(_cdecl),this指针在所有参数被压栈之后压入堆栈

  • 对参数个数不定的,调用者清理堆栈,否则函数自己清理堆栈

5.this指针是否可以为空?

class MyClass  {  public:      int i;      void hello()      {          printf("hello\n");      }      void print()      {          printf("%d\n", i);      }  };  void main()  {      MyClass* pmy = NULL;      pmy->hello();   }

看上面的这段代码,似乎很诡异。 用一个空指针调用成员函数,简直是天大的错误,可以遗憾的是,却是可行的,至少对于上面的这段程序来说,不会照成错误。

为什么?

在类初始化的时候,编译器会将它的函数分配到类的外部,当然这也包括静态成员函数,这样的做法,主要是为了节约内存,这也是为什么静态函数可以在对象初始化之前运行的原因。

大家知道,每个对象,都有一个指向自己的this指针,这个指针的值,将会因为对象的不同而不同,它的作用主要就是用来区分不同的对象,这样你就可以根据它来访问不同的对象的成员变量。

编译器编译后的成员函数的第一个参数是this指针,通过this指针引用数据成员及调用其它成员函数。

main函数中的hello函数并没有使用类中的任何成员变量,所以,它也就不会用到this指针,此时的this指针是NULL。由于你调用的成员函数没有使用到类的数据成员,所以即使传入的this指针为空,从而我们就可以没有障碍的使用hello函数,然而相对的是,如果你在pmy->hello()之后接着调用pmy->print(),那么将会报空指针错误,因为这个函数试图用this指针访问成员变量i。

结论:

1)NULL对象指针可以调用成员函数

2)通过对象调用成员函数,对象的指针会被传入函数中,指针名称为this

3)NULL对象指针调用成员函数时,只要不访问此对象的成员变量,则程序正常运行

4)NULL对象指针调用成员函数时,一旦访问此对象的成员变量,则程序崩溃

你可能感兴趣的文章
第三代合作伙伴计划2(3GPP2, 3rd Generation Partnership Project 2)简介
查看>>
安全隔离网闸简介
查看>>
Javascript中window对象简介
查看>>
HTML Document对象简介
查看>>
HTML location对象简介
查看>>
HTML <span> 标签简介
查看>>
层叠样式表(Cascading Style Sheets,CSS)简介
查看>>
Jsp中include动作指令简介
查看>>
JSP中include指令简介
查看>>
MyEclipse更改jsp默认编码
查看>>
Unrecognized Windows Sockets error: 0: JVM_Bind 异常解决办法
查看>>
HTML <hr>标签简介
查看>>
CDMA2000简介
查看>>
C#中通过wmi获取硬件的信息
查看>>
C#中通过WMI的Win32_DiskDrive对象获取磁盘驱动器信息简介
查看>>
C#中通过WMI的Win32_Processor对象获取CPU信息简介
查看>>
C#中通过WMI的Win32_MemoryDevice对象获取内存信息简介
查看>>
C#中通过WMI的Win32_CDROMDrive对象获取光驱信息简介
查看>>
C#中通过WMI的Win32_QuickFixEngineering对象获取补丁信息简介
查看>>
破解Redhat 5.4 root的密码
查看>>