this指针/常函数、常对象

this指针引入

  类中对象的成员变量和成员函数是分开存储的,sizeof(空class) = 1,另外示例中涉及到字节对齐的问题,double本身的字节为8,int为4,由于字节对齐,int也为8,所以最终字节数为16

 1 class Person{
 2     int m; //非静态成员变量,属于对象  sizeof(Person) = 4
 3     static int n;  //静态成员变量,不属于对象 sizeof(Person) = 4
 4     static void func();  //静态成员函数,不属于对象 sizeof(Person) = 4
 5     void func01();  //非静态成员函数,不属于对象 sizeof(Person) = 4
 6     double p;  //sizeof(Person) = 16 字节对齐 #pragma pack(1)可以取消字节对齐
 7 };
 8 
 9 void test01(){
10     cout << "sizeof(Person) = " << sizeof(Person) << endl;
11 }

  非静态成员变量才属于对象本身,静态成员变量、函数、非静态成员函数(非内联)不属于对象本身

  每一个非内联成员函数只会诞生一份函数实例,多个同类型对象会共用一块代码,由于类中每个实例后的对象都有独一无二的地址,因此不同的实例对象调用成员函数时,函数需要知道是谁在调用它,因此引入了this指针。

this指针原理

  主要作用:为了区分不同的实例对象;解决命名冲突。

  this指针是隐含在对象成员函数内的一种指针。当一个对象被创建后,它的每一个成员函数都会含有一个系统自动生成的隐含指针this。this指针指向被调用的成员函数所属的对象(谁调用成员函数,this指向谁),*this表示对象本身,非静态成员函数中才有this,静态成员函数内部没有。

 1 class Person{
 2 public:
 3     static int m_B;
 4     int m_A;
 5 
 6     Person(int tmp){
 7         m_A = tmp;
 8     }
 9 
10     void test(){
11         m_A = 0;
12     }
13 
14     static void test01(){
15         m_B = 10;
16     }
17 };
18 
19 void Class_test(){
20     int m = 0;
21     Person p(m);
22 }

  编译器对上述代码进行如下处理,对非静态成员函数默认添加了this指针,类型为class *cosnt this

 1 struct Person{
 2     static int m_B;
 3     int m_A;
 4 };
 5 
 6 void Person_Ini(Person *const this, int tmp){ //添加了this指针
 7     this->m_A = tmp;
 8 }
 9 void Person_test(Person *const this){
10     this->m_A = 0;
11 }
12 
13 static void Person_test01(){
14     m_B = 10;
15 }
16 void Person_Class_test(){
17     int m = 0;
18     Person p;
19     Person_Ini(&p, m);
20 
21 }

this指针使用

  一般多用于:(1)当形参与成员变量名相同时,用this指针来区分;(2)在类的非静态成员函数中返回对象本身,可以用return *this,this指向对象,*this表示对象本身。

 1 class Person{
 2 public:
 3     int m_A;
 4 
 5     Person(int m_A){
 6         this->m_A = m_A; //为了区分形参和成员变量同名
 7     }
 8 
 9     //PPlus返回对象可以实现链式编程,如果没引用则返回的是this指向对象的拷贝
10     Person& PPlus(Person p){ 
11         this->m_A += p.m_A;
12         return *this; //返回对象
13     }
14 
15 };
16 
17 void test01(){
18     int m = 10;
19     Person p1(m);
20     Person p2(m);
21 
22     //---------
23     //30
24     p1.PPlus(p1).PPlus(p1); 
25     //---------
26 
27     //---------
28     //40
29     //p1.PPlus(p1);
30     //p1.PPlus(p1);
31     //---------
32 
33     cout << p1.m_A << endl;
34 }

空指针访问成员函数 

  注意:(1)如果成员函数没有用到this,则空指针可以直接访问;(2)若成员函数用到了this,则可以加if判断,如果this为NULL,则直接return掉。

 常函数、常对象

void func() const //常函数

const Person p2; //常对象

  常函数修饰的是this指针,不允许修改this指针指向的值,如果执意要修改常函数,可以在成员属性前加mutable。

  常对象不允许修改属性,不可以调用普通成员函数,可以调用常函数。

 1 class Person{
 2 public:
 3     int m_a;
 4     mutable int m_b;
 5 
 6     void test() const{
 7         //this->m_a = 100; //加了const表示常函数,不可修改this指向的值,其实也是成员属性
 8         this->m_b = 0; //加了mutable,可以修改
 9     }
10 
11     void test02() {
12         this->m_a = 100; //
13         this->m_b = 0; //加了mutable,可以修改
14     }
15 
16 
17 
18 };
19 
20 void test01(){
21     const Person p;
22     //p.m_a = 10; //常对象,不可修改属性值
23     p.test();
24     //p.test02(); //不可调用普通函数
25 }

 

posted @ 2019-01-10 16:37  两猿社  阅读(495)  评论(0编辑  收藏  举报