C++对象模型和this指针详解
目录
- 对象模型
- 一、
- 二、
- 三、
- 四、
- 五、
- this指针
- 一、
- 二、
- 总结
对象模型 成员变量和成员函数分开存储
一、
只有非静态成员变量才属于类的对象上
空对象占用字节为1
class Person{}; void test01(){ Person p; cout << "size of = " << sizeof(p) << endl; }int main(){ test01(); system("pause"); return 0; }
文章图片
占用内存空间为 1 的原因是:如果有其他的空对象,各自分配一个内存空间可以让两者之间相互区别,而且 1 字节也很省内存。 所以每个空对象都会有一个自己的内存地址。
二、
class Person{ int m_A; //改为有内容}; void test02(){ Person p; cout << "size of = " << sizeof(p) << endl; }int main(){ test02(); system("pause"); return 0; }
文章图片
因为 int 类型 ,不把之前的空类型考虑进去。
三、
将Person类改为
class Person{ int m_A; // 非静态成员变量 属于类的对象上 static int m_B; // 添加 静态成员变量 不属于类的对象上}; int Person::m_B = 0;
文章图片
非静态成员变量 属于类的对象上
静态成员变量,不属于类对象上
所以不考虑在内
四、
class Person{ int m_A; // 非静态成员变量 属于类的对象上 static int m_B; // 添加 静态成员变量 不属于类的对象上 void func()//非静态成员函数 { }}; int Person::m_B = 0;
文章图片
所以成员变量和成员函数是分开存储的,非静态成员函数不属于类对象上
五、
static voidfunc()
{}
静态成员函数也不会增加 不属于类对象上
this指针 用于区分类中多个对象调用函数时,分别都是哪个函数在调用自己。
this 指针指向被调用成员函数所属的对象
特点:
【C++对象模型和this指针详解】1. this指针是隐含每一个非静态成员函数内的一种指针
2.this 指针不需要定义,直接使用即可。
用途:
1.当形参和成员变量同名时,可用this指针来区分
2.在类的非静态成员变量中返回对象本身,可使用return *this
一、
class Person{public: Person(int age)//变量 {//this指针指向的是被调用成员函数的所属对象//即 p1, 所以可以解决和变量的名称冲突this->age = age; //前一个为成员变量,后一个age为形参 } int age; }; void test01(){ Person p1(18); cout << "p1的年龄为: " << p1.age << endl; }main(){ test01(); system("pause"); return 0; }
如果不加 this 都会默认为形参 age ,从而报错。
this 指向被调用的对象,此时为 p1。
二、
class Person{public: Person(int age) {//this指针指向的是被调用成员函数的所属对象//即 p1, 所以可以解决和变量的名称冲突this->age = age; } void PersonAddAge(Person &p) {this->age += p.age; } int age; }; void test01(){ Person p1(18); cout << "p1的年龄为: " << p1.age << endl; }//返回对象本身用*this void test02(){ Person p1(10); Person p2(10); p2.PersonAddAge(p1); cout << "p2年龄:" << p2.age << endl; }int main(){ test01(); test02(); system("pause"); return 0; }
此时p2为 20 ,若要多次相加需要改动为
class Person{public: Person(int age) {//this指针指向的是被调用成员函数的所属对象//即 p1, 所以可以解决和变量的名称冲突this->age = age; } Person& PersonAddAge(Person &p)//此处void 改为Peroson是因为返回值如果是p2的话,就可以将p2.PersonAddAge(p1) 看作p2,然后继续调用之后的PersonAddAge(p1) //此处的Person &p是以 引用的方式传入 //此处的Person& 是以引用的方式返回 {this->age += p.age; // this是指向p2的指针,而*this就是p2本体return* this; } int age; }; void test01(){ Person p1(18); cout << "p1的年龄为: " << p1.age << endl; }//返回对象本身用*this void test02(){ Person p1(10); Person p2(10); p2.PersonAddAge(p1).PersonAddAge(p1).PersonAddAge(p1); cout << "p2年龄:" << p2.age << endl; }int main(){ test01(); test02(); system("pause"); return 0; }
文章图片
链式编程思想:可以往后无限的追加。
但如果函数,不使用引用方法,返回的是一个值,就会创建新的对象
Person PersonAddAge(Person &p)//不使用引用方法 {this->age += p.age; // this是指向p2的指针,而*this就是p2本体return* this; } int age; };
在第一次调用Person PersonAddAge()后 ,p2加了10, 但在这之后返回的并不是本体了,而是根据本体创建的一个新的数据。Person 和 *this 是不一样的数据(见拷贝构造函数的调用时机-以值方式返回局部对象)。 所以每一次Person PersonAddAge()后,都是一个新的对象,所以最后输出结果p2 是不变的20。
疑问:至于为什么不是p2 为 10 。 以值方式返回局部对象会调用拷贝构造函数。对p2进行一次PersonAddAge操作后,将p2的结果拷贝为p2' 。所以p2还是经过了一次加年龄的操作的 。对p2进行一次PersonAddAge操作后,将p2的结果拷贝为p2'
总结 本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- opencv|opencv C++模板匹配的简单实现
- 数组常用方法一
- C语言学习|第十一届蓝桥杯省赛 大学B组 C/C++ 第一场
- jQuery插件
- iOS面试题--基础
- 口红选得好,对象不愁找......
- Flutter的ListView
- c++基础概念笔记
- 一般模型化关系——从模型是什么到如何起作用的基本答案
- java静态代理模式