zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    分享一些优化博客的心得
    HTTP相关整理(上)
    正则&highlight高亮实现(干货)
    通过一个demo了解Redux
    升级ChinaCock10.3.3激情版3注意事项
    解决uniDAC超时问题:已超过了锁请求超时时段。
    kbmMWSmartBind实现ListView绑定数据集进阶篇(一)
    通过输出日志到文件来检查app闪退原因
    VertScrollBox不能滑动
    使用kbmMW SmartBinding经验几则
  • 原文地址:https://www.cnblogs.com/qinguoyi/p/10250843.html
Copyright © 2011-2022 走看看