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 //3024 p1.PPlus(p1).PPlus(p1); 25 //---------26 27 //---------28 //4029 //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 }