当前位置:   article > 正文

C++:类和对象:C++对象模型和 this指针_int main(){ const person person1;//常量对象 person per

int main(){ const person person1;//常量对象 person person2;//正常对象 //正常

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

在C++中,类内的成员变量和成员函数分开存储,只有非静态成员变量才属于类对象。

案例:我们写一个空类,然后创建一个对象,看看这个空对象占用多大空间。

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Person {
  5. };
  6. void test() {
  7. Person p;
  8. cout << "size of p is: " << sizeof(p) << endl;
  9. }
  10. int main() {
  11. test();
  12. return 0;
  13. }

 运行结果可知:

   空对象大小为1字节,这是因为编译器为了区分空对象占用内存位置,给每个空对象也会分配一个独一无二的内存地址。

 案例:我们写在这个类中添加一个  int 类型的成员变量 m_A。

  1. #include <iostream>
  2. using namespace std;
  3. #include <string>
  4. class Person
  5. {
  6. int m_A;
  7. };
  8. void test01()
  9. {
  10. Person p;
  11. cout << "size of p is: " << sizeof(p) << endl;
  12. }
  13. int main()
  14. {
  15. test01();
  16. return 0;
  17. }

 运行结果可知:

包含一个int类型成员变量,这个对象的大小是 4字节。

 当我们增加静态成员变量,静态成员函数,非静态成员函数时。

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Person {
  5. int m_A;
  6. static int m_B;
  7. static void func() {};
  8. void func1() {};
  9. };
  10. void test() {
  11. Person p;
  12. cout << "size of p is: " << sizeof(p) << endl;
  13. }
  14. int main() {
  15. test();
  16. return 0;
  17. }

 运行结果可知:

      不管是静态成员函数,成员韩式,静态成员变量,均不会增加这个对象所占内存大小。

2:this指针 

问题

Question :  在C++ 中成员变量和成员函数是分开存储的,每一个非静态成员函数只会诞生一份函数实例,也就是说多个同类型的对象会公用一块代码,那么问题是:这一块代码是如何区分到底哪个对象调用自己的了 ?

Answer:   C++通过提供特殊的对象指针(this指针)来解决上述问题。this指针指向被调用的成员函数所属的对象。 this指针是隐含每一个非静态成员函数的一种指针。 this指针不需要定义,可以直接使用。

this指针用途:

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

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

案例:现在我们想增加一个成员函数,实现将一个对象的年龄加到另一个对象的年龄上。 

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Person {
  5. public:
  6. Person(int age) {
  7. // 1:当形参和成员变量同名时,可用 this指针加以区分。
  8. this->age = age;
  9. }
  10. Person& PersonAddPerson(Person& p) {
  11. this->age += age;
  12. return *this;
  13. }
  14. int age;
  15. };
  16. void test() {
  17. Person p1(10);
  18. cout << "p1.age = " << p1.age << endl;
  19. Person p2(10);
  20. p2.PersonAddPerson(p1).PersonAddPerson(p1).PersonAddPerson(p1);
  21. cout << "p2.age = " << p2.age << endl;
  22. }
  23. int main() {
  24. test();
  25. return 0;
  26. }

运行结果可知:由于每次执行 PersonAddPerson()函数都能返回当前对象,所以可以实现当前对象p2(age的累加)。 

3:空指针访问成员函数

在C++中空指针也是可以调用成员函数的,但是也需要注意是否使用到 this指针,如果用到 this指针,那么我们就需要添加判断保证代码的健壮性。

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Person {
  5. public:
  6. void ShowPerson() {
  7. cout << "showPerson enter" << endl;
  8. }
  9. int age;
  10. };
  11. void test() {
  12. // Null空指针是可以调用成员函数的
  13. Person* p = NULL;
  14. p->ShowPerson();
  15. }
  16. int main() {
  17. test();
  18. return 0;
  19. }

如果:成员函数中用到了 this指针,就是不可以的,就需要对this进行判断。

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Person {
  5. public:
  6. void ShowPerson() {
  7. // 事实上属性的前面都是默认添加了 this , 即等同于 this.age 。
  8. if (this == NULL)
  9. {
  10. cout << "当前 person对象为空" << endl;
  11. }
  12. else
  13. {
  14. cout << age << endl;
  15. }
  16. }
  17. int age;
  18. };
  19. void test() {
  20. // Null空指针是可以调用成员函数的,但是一旦成员函数使用了 this 就是不可以的
  21. Person* p = NULL;
  22. p->ShowPerson();
  23. }
  24. int main() {
  25. test();
  26. return 0;
  27. }

4:const修饰成员函数、修饰对象

常函数:

1:  成员函数后加 const,我们称这个函数为  常函数。

2:常函数内不可以修改成员属性。

3:但是成员属性声明时加关键字 mutable ,那么在常函数中依然可以修改。

案例:常函数无法修改普通的成员变量,但是可以修改 mutable修饰的成员变量 。

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Person {
  5. public:
  6. /**
  7. this 指针的本质时一个 指针常量 Person* const this,指针的指向不可以修改,但是指向的值可以修改
  8. 如果想让指针指向的值也不可修改,那么就需要声明为 常函数,在函数的参数列表后添加 const
  9. 这样 this 指针就变成 : const Person* const this
  10. */
  11. void ShowPerson() const {
  12. // this = NULL; // 不能修改指针的指向
  13. // this->m_A = 100; //指针this指向的对象的数据也不能修改。
  14. this->m_B = 100; // mutable修饰的变量时可以修改的。
  15. }
  16. int m_A;
  17. mutable int m_B;
  18. };
  19. int main() {
  20. return 0;
  21. }

常对象:

1:声明对象前 添加 const,那么称该对象为 常对象,常对象无法修改成员变量的值

2:如果成员变量添加了 mutable ,那么常对象可以修改这个成员变量的值

3:常对象只能调用常函数,因为普通函数可能会修改 成员变量的值

  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. class Person {
  5. public:
  6. // 常函数
  7. void MyFunc()const {}
  8. // 普通函数
  9. void MyFunc2() {}
  10. // 普通变量
  11. int m_A;
  12. // mutable 可变变量
  13. mutable int m_B;
  14. };
  15. int main() {
  16. const Person person; // 常量对象
  17. person.MyFunc(); // 常量对象只能调用常量函数
  18. person.m_A = 100; // 常量对象不能修改普通成员变量
  19. person.m_B = 100; // 常量对象可以修改 mutable修饰的成员变量
  20. person.MyFunc2(); // 常量对象也不能调用普通函数
  21. return 0;
  22. }

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/505411
推荐阅读
相关标签
  

闽ICP备14008679号