C++对象模型和this指针实例分析

简介: 成员变量和成员函数分开存储在C++中,类内的成员变量和成员函数分开存储只有非静态成员变量才属于类的对象上class Person {public: Person() { mA = 0; } //非静态成员变量占对象空间 int mA; //静态成员变量不占对象空间 static int mB; //函数也不占对象空间,所有函数共享一个函数实例 ——关键,原因见下讲。 void func() {


C++对象模型和this指针

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

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

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

classPerson {

public:

   Person() {

       mA=0;

   }

   //非静态成员变量占对象空间

   intmA;

   //静态成员变量不占对象空间

   staticintmB;

   //函数也不占对象空间,所有函数共享一个函数实例 ——关键,原因见下讲。

   voidfunc() {

       cout<<"mA:"<<this->mA<<endl;

   }

   //静态成员函数也不占对象空间

   staticvoidsfunc() {

   }

};

intmain() {

   cout<<sizeof(Person) <<endl;

   system("pause");

   return0;

}

PS:注意:一个空的类只占一个字节(为了区分空对象所占内存的位置),但是类里有了非静态成员变量后就占变量所对应的字节。

this指针概念

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

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

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

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

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

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

this指针的用途:

  • 1.解决名称冲突:当形参和成员变量同名时,可用this指针来区分
  • 2.在类的非静态成员函数中返回对象本身,可使用return *this
    1.e.g.注意以下代码:传入的形参并不会给成员属性age赋值!(注意灰色阴影)
    网络异常,图片无法展示
    |

    解决方法:
    1.加上this指针,见下图。2.规范书写,比如改成m_Age
    网络异常,图片无法展示
    |

classPerson

{

public:

   Person(intage)

   {

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

       this->age=age;

   }

   Person&PersonAddPerson(Personp)

   {

       this->age+=p.age;

       

       return*this;//返回对象本身!

   }

   intage;

};

voidtest01()

{

   Personp1(10);

   cout<<"p1.age = "<<p1.age<<endl;

   Personp2(10);

   p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);//链式编程思想

   cout<<"p2.age = "<<p2.age<<endl;

}

intmain() {

   test01();

   system("pause");

   return0;

}

空指针访问成员函数

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

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

示例:

//空指针访问成员函数

classPerson {

public:

   voidShowClassName() {

       cout<<"我是Person类!"<<endl;

   }

   voidShowPerson() {

       if (this==NULL) {

           return;

       }

       cout<<mAge<<endl;

   }

public:

   intmAge;

};

voidtest01()

{

   Person*p=NULL;

   p->ShowClassName(); //空指针,可以调用成员函数

   p->ShowPerson();  //但是如果成员函数中用到了this指针,就不可以了

}

intmain() {

   test01();

   system("pause");

   return0;

}

const修饰成员函数

常函数:

  • 成员函数后加const后我们称为这个函数为常函数
  • 常函数内不可以修改成员属性
  • 成员属性声明时加关键字mutable后,在常函数中依然可以修改

常对象:

  • 声明对象前加const称该对象为常对象
  • 常对象只能调用常函数

示例:

//常函数

classPerson {

public:

   Person() {

       m_A=0;

       m_B=0;

   }

   //this指针的本质是一个指针常量,指针的指向不可修改

   //如果想让指针指向的值也不可以修改,需要声明常函数

   voidShowPerson() const {

       //常函数本质:const Type* const pointer;常函数的const本身修饰的是this指针,导致指针指向的值和地址都不可改。

       

       //this = NULL; //不能修改指针的指向 Person* const this;

       //this->mA = 100; //mA = 100在本函数中的本质是this->mA = 100其中this指针是指针常量,this指针指向的对象的数据是可以修改的,但是加上const声明为常函数后其值也不可以修改了。

       //const修饰成员函数,表示指针指向的内存空间的数据不能修改,除了mutable修饰的变量

       this->m_B=100;

   }

   voidMyFunc() const {

       //mA = 10000;

   }

public:

   intm_A;

   mutableintm_B; //可修改 可变的

};

//const修饰对象  常对象

voidtest01() {

   constPersonperson; //常量对象  

   cout<<person.m_A<<endl;

   //person.mA = 100; //常对象不能修改成员变量的值,但是可以访问

   person.m_B=100; //但是常对象可以修改mutable修饰成员变量

   //常对象访问成员函数

   person.MyFunc(); //常对象不能调用普通成员函数,因为普通成员函数可以修改属性。

}

intmain() {

   test01();

   system("pause");

   return0;

}

PS:加上const指向和值都不可以修改了。

网络异常,图片无法展示
|


目录
相关文章
|
4月前
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
64 2
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
C++构建 GAN 模型:生成器与判别器平衡训练的关键秘籍
生成对抗网络(GAN)是AI领域的明星,尤其在C++中构建时,平衡生成器与判别器的训练尤为关键。本文探讨了GAN的基本架构、训练原理及平衡训练的重要性,提出了包括合理初始化、精心设计损失函数、动态调整学习率、引入正则化技术和监测训练过程在内的五大策略,旨在确保GAN模型在C++环境下的高效、稳定训练,以生成高质量的结果,推动AI技术的发展。
71 10
|
2月前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
172 4
|
3月前
|
存储 编译器 C语言
C++入门2——类与对象1(类的定义和this指针)
C++入门2——类与对象1(类的定义和this指针)
58 2
|
3月前
对象指针输出时分秒
对象指针输出时分秒
14 0
|
3月前
|
算法 C++
【算法】双指针+二分(C/C++
【算法】双指针+二分(C/C++
|
5月前
|
编译器 C++
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
virtual类的使用方法问题之静态和非静态函数成员在C++对象模型中存放如何解决
|
5月前
|
编译器 C++
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
virtual类的使用方法问题之在C++中获取对象的vptr(虚拟表指针)如何解决
112 4
|
6月前
|
存储 安全 C++
浅析C++的指针与引用
虽然指针和引用在C++中都用于间接数据访问,但它们各自拥有独特的特性和应用场景。选择使用指针还是引用,主要取决于程序的具体需求,如是否需要动态内存管理,是否希望变量可以重新指向其他对象等。理解这二者的区别,将有助于开发高效、安全的C++程序。
43 3
|
6月前
|
C++ 索引 运维
开发与运维数组问题之在C++中数组名和指针是等价如何解决
开发与运维数组问题之在C++中数组名和指针是等价如何解决
45 6