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指向和值都不可以修改了。

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


目录
相关文章
|
2月前
|
编译器 C++
C++之类与对象(完结撒花篇)(上)
C++之类与对象(完结撒花篇)(上)
37 0
|
10天前
|
机器学习/深度学习 人工智能 自然语言处理
C++构建 GAN 模型:生成器与判别器平衡训练的关键秘籍
生成对抗网络(GAN)是AI领域的明星,尤其在C++中构建时,平衡生成器与判别器的训练尤为关键。本文探讨了GAN的基本架构、训练原理及平衡训练的重要性,提出了包括合理初始化、精心设计损失函数、动态调整学习率、引入正则化技术和监测训练过程在内的五大策略,旨在确保GAN模型在C++环境下的高效、稳定训练,以生成高质量的结果,推动AI技术的发展。
33 10
|
21天前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
54 5
|
27天前
|
存储 编译器 C++
【c++】类和对象(中)(构造函数、析构函数、拷贝构造、赋值重载)
本文深入探讨了C++类的默认成员函数,包括构造函数、析构函数、拷贝构造函数和赋值重载。构造函数用于对象的初始化,析构函数用于对象销毁时的资源清理,拷贝构造函数用于对象的拷贝,赋值重载用于已存在对象的赋值。文章详细介绍了每个函数的特点、使用方法及注意事项,并提供了代码示例。这些默认成员函数确保了资源的正确管理和对象状态的维护。
56 4
|
28天前
|
存储 编译器 Linux
【c++】类和对象(上)(类的定义格式、访问限定符、类域、类的实例化、对象的内存大小、this指针)
本文介绍了C++中的类和对象,包括类的概念、定义格式、访问限定符、类域、对象的创建及内存大小、以及this指针。通过示例代码详细解释了类的定义、成员函数和成员变量的作用,以及如何使用访问限定符控制成员的访问权限。此外,还讨论了对象的内存分配规则和this指针的使用场景,帮助读者深入理解面向对象编程的核心概念。
66 4
|
29天前
|
Ubuntu Linux Shell
C++ 之 perf+火焰图分析与调试
【11月更文挑战第6天】在遇到一些内存异常的时候,经常这部分的代码是很难去进行分析的,最近了解到Perf这个神器,这里也展开介绍一下如何使用Perf以及如何去画火焰图。
|
2月前
|
存储 安全 编译器
在 C++中,引用和指针的区别
在C++中,引用和指针都是用于间接访问对象的工具,但它们有显著区别。引用是对象的别名,必须在定义时初始化且不可重新绑定;指针是一个变量,可以指向不同对象,也可为空。引用更安全,指针更灵活。
|
2月前
|
存储 编译器 对象存储
【C++打怪之路Lv5】-- 类和对象(下)
【C++打怪之路Lv5】-- 类和对象(下)
29 4
|
2月前
|
编译器 C语言 C++
【C++打怪之路Lv4】-- 类和对象(中)
【C++打怪之路Lv4】-- 类和对象(中)
25 4
|
2月前
|
Ubuntu Linux Shell
C++ 之 perf+火焰图分析与调试
【10月更文挑战第8天】在遇到一些内存异常的时候,经常这部分的代码是很难去进行分析的,最近了解到Perf这个神器,这里也展开介绍一下如何使用Perf以及如何去画火焰图。