C++中的 对象模型与this指针

目录

1 成员变量与成员函数分开存储

2 this指针

2.1 作用1

2.1.1示例

2.2 作用2

3 空指针访问成员函数

4 const修饰成员函数

4.1示例

4.2 常对象


1 成员变量与成员函数分开存储

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

首先,对于一个空对象,占用内存空间为1

 class person
 {
 ​
 };
 ​
 void test01()
 {
   person p;
   cout << sizeof(p) << endl;
 }

img

因为C++编译器给每个空对象分配1个字节空间,防止不同空对象占用同一块内存空间,便于区分


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

在person类中加入一个非静态成员变量

 class person
 {
   int m_a; // 非静态成员变量,属于类的对象上
 };
 ​
 void test02()
 {
   person p;
   cout << sizeof(p) << endl;
 }

img

再加上静态成员变量

img

再加上非静态成员函数

img

最后加上静态成员函数

img

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

2 this指针

概念:上一节中我们知道成员变量与成员函数分开存储,每一个非静态成员函数只会产生一份函数实例,也就是多个同类型的对象共用一块代码,而如何区分究竟是哪个对象调用自己,用到this指针

this指针指向被调用的成员函数所属的对象

性质:

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

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

2.1 作用1

当形参与成员变量同名时,可用this指针加以区分

2.1.1示例

我们先创建类person和测试函数test01,在类内创建属性m_age,函数person,形参age

 class person
 {
 public:
   person(int age)
   {
     m_age = age;
   }
   int m_age;
 };
 void test01()
 {
   person p(20);
   cout << p.m_age << endl;
 }

此时可正常输出

但是,如果我们将属性m_age改为age得到这个

 class person
 {
 public:
   person(int age)
   {
     age = age;
   }
   int age;
 };
 void test01()
 {
   person p(20);
   cout << p.age << endl;
 }

img

同颜色的即为同一个age,无法正常输出

在此基础上,我们在函数内加上this指针

 class person
 {
 public:
   person(int age)
   {
     this->age = age; // 加上this->
   }
   int age;
 };

img

可以发现3个age是同源的。此时,this就代表pthis->age == p.age;

img


2.2 作用2

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

 class person
 {
 public:
   person(int age)
   {
     this->age = age;
   }
   void personAdd(person& p) // 函数本体age加上参数P的age
   {
     this->age += p.age;
   }
   int age;
 };
 void test02()
 {
   person p1(10);
   cout << p1.age << endl;
   person p2(10);
   cout << p2.age << endl;
 }

img

而如果我们想要多次加和

 void test02()
 {
   p2.personAdd(p1);
   cout << p2.age << endl;
 ​
   p2.personAdd(p1).personAdd(p1).personAdd(p1); // 想要多次加和
   cout << p2.age << endl;
 }

img

要先修改函数体返回值

 person& personAdd(person& p) // 而且要引用
   {
     this->age += p.age;
     return *this; // 返回对象本身
   }

img

而如果函数体返回值不使用引用&,则无法修改值

img

因为这样修改完第一次p2后,返回的是另一个变量,并且后面第2次开始修改的都是另一个变量,再另一个变量

3 空指针访问成员函数

C++中空指针也可以调用成员函数,不过要注意是否用到this指针

如果遇到this指针,加上判断,防止代码出错

 class person
 {
 public:
   void show_name()
   {
     cout << "Joyce" << endl;
   }
   void show_age()
   {
     cout << this->m_age << endl;
   }
 ​
   int m_age;
 ​
 };
 void test01()
 {
   person* p = NULL;
   p->show_age(); // 非法访问
   p->show_name();
 }

对于这段代码,指针p为NULL,调用show_name函数时可以正常输出,因为她只是简单的打印特定的内容,而调用show_age函数时将报错,因为函数内this->m_age;调用了this指针的m_age,而this指针为NULL,造成非法访问

因此,我们在函数内部加上判断

 void show_age()
   {
     if (this == NULL)
     {
       return;
     }
     cout << this->m_age << endl;
   }

以此便可以防止代码为NULL时出错

4 const修饰成员函数

常函数:

  • 成员函数后加const称该函数为成员函数

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

  • 成员属性声明时加关键字mutable,在常函数中仍然能修改

4.1示例

接下来创建person类与函数show_name;

 class person
 {
 public:
   void show_name()
   {
     this->m_a = 100; // 非 常对象,可修改
     this = NULL;// this指针的指向不可修改
   }
   int m_a;
 };

img

因为this指针本质是一个指针常量,所以其指向(地址)不可修改,但其指向的值可以修改

本质person * const this;


不过,如果在函数加上const,则地址与值都不可修改

本质const person \*const this;

img

不过,如果在常函数中的属性的声明前加上mutable,则可以修改

 class person
 {
 public:
   void show_name() const // 这里有const
   {
     this->m_a = 100; //可修改
   }
   mutable int m_a; // 加上const
 };

4.2 常对象

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

  • 常对象只能调用常函数

 class person
 {
 public:
   void show_name() const
   {
     this->m_a = 100; 
   }
   mutable int m_a;
   int m_b;
 };
 void test02()
 {
   person p;
   p.m_b = 20; 
 }

此时test02内可以修改m_b;接下来在p前加上const使其变成常对象

 void test02()
 {
   const person p;
   p.m_b = 20; // 不可修改
   p.m_a = 20; // 可修改
 }

m_b不可修改,而m_a由于前面加了mutable,可以修改

img


同时,在person类中我们再创建一个普通函数func,尝试在test函数中调用刚才的常函数和普通函数

 class person
 {
 public:
   void show_name() const // 常函数
   {
     this->m_a = 100; 
   }
   void func() // 普通函数
   {
     ;
   }
   mutable int m_a;
   int m_b;
 };
 ​
 void test02()
 {
     const person p; // 创建常对象
   p.show_name(); // 常函数
   p.func(); // 普通函数
 }

img

无法调用,因为常对象只能调用常函数(因为普通函数可以修改属性)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值