• 第十四章 类和对象——C++对象模型和this指针


    一、成员变量和成员函数分开存储

    在C++中,类内的成员变量和成员函数分开存储

    只有非静态成员变量才属于类的对象上

    1.  class Person {
    2.  public:
    3.   Person() {
    4.   mA = 0;
    5.   }
    6.   //非静态成员变量占对象空间
    7.   int mA;
    8.   //静态成员变量不占对象空间
    9.   static int mB;
    10.   //函数也不占对象空间,所有函数共享一个函数实例
    11.   void func() {
    12.   cout << "mA:" << this->mA << endl;
    13.   }
    14.   //静态成员函数也不占对象空间
    15.   static void sfunc() {
    16.   }
    17.  };
    18.  ​
    19.  int main() {
    20.  ​
    21.   cout << sizeof(Person) << endl;
    22.  ​
    23.   system("pause");
    24.  ​
    25.   return 0;
    26.  }

    二、this指针概念

    通过上面,我们知道在C++中成员变量和成员函数是分开存储的

    每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会共用一块代码

    那么问题是:这一块代码是如何区分哪个对象调用自己的呢?

    c++通过提供特殊的对象指针,this指针,解决上述问题。this指针指向被调用的成员函数所属的对象

    this指针是隐含每一个非静态成员函数内的一种指针

    this指针不需要定义,直接使用即可

    this指针的用途:

    • 当形参和成员变量同名时,可用this指针来区分

    • 在类的非静态成员函数中返回对象本身,可使用return *this

    1.  class Person
    2.  {
    3.  public:
    4.  ​
    5.   Person(int age)
    6.   {
    7.   //1、当形参和成员变量同名时,可用this指针来区分
    8.   this->age = age;
    9.   }
    10.  ​
    11.   Person& PersonAddPerson(Person p)
    12.   {
    13.   this->age += p.age;
    14.   //返回对象本身
    15.   return *this;
    16.   }
    17.  ​
    18.   int age;
    19.  };
    20.  ​
    21.  void test01()
    22.  {
    23.   Person p1(10);
    24.   cout << "p1.age = " << p1.age << endl;
    25.  ​
    26.   Person p2(10);
    27.   p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
    28.   cout << "p2.age = " << p2.age << endl;
    29.  }
    30.  ​
    31.  int main() {
    32.  ​
    33.   test01();
    34.  ​
    35.   system("pause");
    36.  ​
    37.   return 0;
    38.  }
    1.  class Person
    2.  {
    3.  public:
    4.  ​
    5.   Person(int age)
    6.   {
    7.   //1、当形参和成员变量同名时,可用this指针来区分
    8.   this->age = age;
    9.   }
    10.  
    11.      // 不返回引用时的情况,此时会返回当前对象的一份拷贝数据
    12.   Person PersonAddPerson(Person p)
    13.   {
    14.   this->age += p.age;
    15.   return *this;
    16.   }
    17.  ​
    18.   int age;
    19.  };
    20.  ​
    21.  void test01()
    22.  {
    23.   Person p1(10);
    24.   cout << "p1.age = " << p1.age << endl;
    25.  ​
    26.   Person p2(10);
    27.   p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
    28.      //
    29.   cout << "p2.age = " << p2.age << endl; //p2.age = 20
    30.      
    31.      // 为什么是20,而不是40呢?
    32.      // 因为p2.PersonAddPerson(p1)调用完该函数返回的是p2对象的一份拷贝,也就是一个新对象,并不是p2对象本身,所以p2对象的age值只加了一次,之后一直都是新产生的对象在加
    33.  }
    34.  ​
    35.  int main() {
    36.  ​
    37.   test01();
    38.  ​
    39.   system("pause");
    40.  ​
    41.   return 0;
    42.  }

    三、空指针访问成员函数

    C++中空指针也是可以调用成员函数的,但是也要注意有没有用到this指针

    如果用到this指针,需要加以判断保证代码的健壮性

    示例:

    1.  //空指针访问成员函数
    2.  class Person {
    3.  public:
    4.  ​
    5.   void ShowClassName() {
    6.   cout << "我是Person类!" << endl;
    7.   }
    8.  ​
    9.   void ShowPerson() {
    10.   if (this == NULL) {
    11.   return;
    12.   }
    13.   cout << mAge << endl;
    14.   }
    15.  ​
    16.  public:
    17.   int mAge;
    18.  };
    19.  ​
    20.  void test01()
    21.  {
    22.   Person * p = NULL;
    23.   p->ShowClassName(); //空指针,可以调用成员函数
    24.   p->ShowPerson();  //但是如果成员函数中用到了this指针,就不可以了
    25.  }
    26.  ​
    27.  int main() {
    28.  ​
    29.   test01();
    30.  ​
    31.   system("pause");
    32.  ​
    33.   return 0;
    34.  }

    四、const修饰成员函数

    常函数:

    • 成员函数后加const后我们称为这个函数为常函数

    • 常函数内不可以修改成员属性

    • 成员属性声明时加关键字mutable后,在常函数中依然可以修改

    常对象:

    • 声明对象前加const称该对象为常对象

    • 常对象只能调用常函数,因为普通成员函数可以修改属性

    示例:

    1.  class Person {
    2.  public:
    3.   Person() {
    4.   m_A = 0;
    5.   m_B = 0;
    6.   }
    7.  ​
    8.   //this指针的本质是一个指针常量,指针的指向不可修改
    9.   //如果想让指针指向的值也不可以修改,需要声明常函数
    10.   void ShowPerson() const {
    11.   //const Type* const pointer;
    12.   //this = NULL; //不能修改指针的指向 Person* const this;
    13.   //this->mA = 100; //但是this指针指向的对象的数据是可以修改的
    14.  ​
    15.   //const修饰成员函数,表示指针指向的内存空间的数据不能修改,除了mutable修饰的变量
    16.   this->m_B = 100;
    17.   }
    18.  ​
    19.   void MyFunc() const {
    20.   //mA = 10000;
    21.   }
    22.  ​
    23.  public:
    24.   int m_A;
    25.   mutable int m_B; //可修改 可变的
    26.  };
    27.  ​
    28.  ​
    29.  //const修饰对象 常对象
    30.  void test01() {
    31.  ​
    32.   const Person person; //常量对象  
    33.   cout << person.m_A << endl;
    34.   //person.mA = 100; //常对象不能修改成员变量的值,但是可以访问
    35.   person.m_B = 100; //但是常对象可以修改mutable修饰成员变量
    36.  ​
    37.   //常对象访问成员函数
    38.   person.MyFunc(); //常对象不能调用const的函数
    39.  ​
    40.  }
    41.  ​
    42.  int main() {
    43.  ​
    44.   test01();
    45.  ​
    46.   system("pause");
    47.  ​
    48.   return 0;
    49.  }

  • 相关阅读:
    【数据结构】栈与队列的实现
    仿mudou库one thread one loop式并发服务器
    sql 调优
    在 JavaScript 中深度克隆对象
    Ubuntu 软件安装方法(入门必看)
    计算机毕业设计Java家用饰品在线销售系统(源码+系统+mysql数据库+lw文档)
    视频会议+无纸化会议融合会议如何实现?
    python 基础语法和基本概念
    高情商的正确表达方式都在这,建议收藏备用
    浙江大学机器学习(胡浩基)学习笔记二:人工神经网络、深度学习
  • 原文地址:https://blog.csdn.net/qq_26126363/article/details/133528646