【C++漂流记】C++对象模型和this指针

矫情吗;* 2024-02-27 06:17 86阅读 0赞

C++中对象模型和this指针是面向对象编程中的重要概念。对象模型描述了对象在内存中的布局和行为,包括成员变量和成员函数的存储方式和访问权限。this指针是一个隐含的指针,指向当前对象的地址,用于在成员函数中引用当前对象的成员变量和成员函数。对象模型和this指针的理解和应用,对于深入理解C++的面向对象特性和实现细节至关重要。
在这里插入图片描述


文章目录

      1. 成员变量和成员函数分开存储
      1. this指针概念
      1. 空指针访问成员函数
      1. const修饰成员函数
      • 常函数:
      • 常对象:

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

在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. int main() {
  19. cout << sizeof(Person) << endl;
  20. system("pause");
  21. return 0;
  22. }

上面的代码定义了一个名为Person的类。Person类有一个默认构造函数,用于初始化非静态成员变量mA为0。Person类还有一个非静态成员变量mA和一个静态成员变量mB。静态成员变量mB不占用对象的空间,而是在全局数据区分配内存。Person类还有一个成员函数func(),用于输出非静态成员变量mA的值。成员函数也不占用对象的空间,所有对象共享一个函数实例。Person类还有一个静态成员函数sfunc(),也不占用对象的空间。在main函数中,使用sizeof运算符输出Person类的大小。最后调用system("pause")暂停程序的执行,返回0表示程序正常结束。


2. this指针概念

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

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

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

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

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

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

this指针的用途:

  • 当形参和成员变量同名时,可用this指针来区分
  • 在类的非静态成员函数中返回对象本身,可使用return *this
  1. class Person
  2. {
  3. public:
  4. Person(int age)
  5. {
  6. //1、当形参和成员变量同名时,可用this指针来区分
  7. this->age = age;
  8. }
  9. Person& PersonAddPerson(Person p)
  10. {
  11. this->age += p.age;
  12. //返回对象本身
  13. return *this;
  14. }
  15. int age;
  16. };
  17. void test01()
  18. {
  19. Person p1(10);
  20. cout << "p1.age = " << p1.age << endl;
  21. Person p2(10);
  22. p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
  23. cout << "p2.age = " << p2.age << endl;
  24. }
  25. int main() {
  26. test01();
  27. system("pause");
  28. return 0;
  29. }

这段代码定义了一个Person类,其中包含一个构造函数和一个成员函数PersonAddPersontest01函数创建了两个Person对象p1p2,并测试了PersonAddPerson函数的功能。

在构造函数中,使用了this指针来区分形参和成员变量。this指针指向当前对象,可以通过this->age来访问成员变量age

PersonAddPerson函数接受一个Person对象作为参数,将该对象的age加到当前对象的age上,并返回当前对象的引用。

test01函数中,首先创建了一个age为10的Person对象p1,并输出其age值。然后创建了另一个age为10的Person对象p2,并连续三次调用PersonAddPerson函数,每次传入p1作为参数。最后输出p2age值。

由于PersonAddPerson函数返回的是当前对象的引用,所以可以连续调用该函数。因此,p2age值会依次增加30,最终输出为40。


3. 空指针访问成员函数

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

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

示例:

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

这段代码定义了一个Person类,其中包含两个成员函数ShowClassNameShowPerson,以及一个成员变量mAgetest01函数创建了一个空指针p,并尝试调用p的成员函数。

在C++中,空指针是指向任何对象的指针,因此可以通过空指针调用成员函数。在ShowClassName函数中,没有使用this指针,所以可以正常调用,输出结果为”我是Person类!“。

但是在ShowPerson函数中,使用了this指针来访问成员变量mAge。当空指针调用该函数时,this指针为NULL,因此访问成员变量时会出现错误。为了避免空指针访问,可以在函数体内通过判断this是否为NULL来提前返回,不执行后续代码。

总结:空指针可以调用成员函数,但是如果成员函数中使用了this指针来访问成员变量,需要注意空指针的处理,避免出现错误。


4. const修饰成员函数

常函数:

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

常对象:

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

示例:

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

这段代码定义了一个名为Person的类。Person类有一个默认构造函数,用于初始化成员变量m_Am_B为0。Person类还有一个成员函数ShowPerson(),使用const修饰,表示该函数是一个常函数。常函数中的this指针是一个指针常量,指针的指向不可修改。但是,常函数可以修改this指针指向的对象的mutable修饰的成员变量m_B的值。Person类还有一个成员函数MyFunc(),同样使用const修饰,但该函数尝试修改成员变量m_A的值,因此会导致编译错误。

main函数中,定义了一个常量对象person,使用const修饰。常量对象不能修改成员变量的值,但可以访问成员变量的值。常量对象可以修改mutable修饰的成员变量m_B的值。常量对象也可以调用常函数ShowPerson(),但无法调用MyFunc()

最后调用system("pause")暂停程序的执行,返回0表示程序正常结束。

发表评论

表情:
评论列表 (有 0 条评论,86人围观)

还没有评论,来说两句吧...

相关阅读

    相关 C++d对象this指针

    一、成员变量与成员函数分开存储。 在C++中,类内的成员变量和成员函数是分开储存的,只有非静态成员变量才属于类的对象上。 \include <iostream> us

    相关 c++笔记----this指针

    this指针 1. this是一个特殊的指针 1. 指向调用该成员函数的那个对象。 2. 是一个隐含每一个非静态成员函数的特殊指针。 1. 对象调

    相关 C++ this 指针

    C++ this 指针 在 C++ 中,每一个对象都能通过 `this` 指针来访问自己的地址。`this` 指针是所有成员函数的隐含参数。在成员函数内部,它可以用来指向

    相关 c++ this 指针

    1. this指针的用处:   一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类的非

    相关 C++——this指针

     一 this指针的使用(成员函数中) 当通过一个对象调用成员函数时,编译器会把当前对象的地址传递给this指针;(this指针保存的是当前对象的地址) //thi