C++对象模型和this指针详解

 更新时间:2021年10月29日 09:45:22   作者:渐迷人眼-  
这篇文章主要介绍了详解C++对象模型和this指针,是C++入门学习中的基础知识,需要的朋友可以参考下,希望能够给你带来帮助

对象模型

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

一、

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

空对象占用字节为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 指针指向被调用成员函数所属的对象

特点:

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'

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!

相关文章

  • C++用winapi socket实现局域网语音通话功能

    C++用winapi socket实现局域网语音通话功能

    这篇文章主要介绍了socket实现局域网语音通话 c++ winapi,功能介绍支持录音设备查找以及播放设备查找,支持局域网语音通话,通话包含语音来电提醒和挂断电话的提示信息,还能实时的获取在线用户的数量以及对应的id,需要的的朋友一起看看
    2022-06-06
  • Qt 关于容器的遍历迭代器的使用问题小结

    Qt 关于容器的遍历迭代器的使用问题小结

    Qt是一个跨平台的 C++ 开发库,主要用来开发图形用户界面程序,当然也可以开发不带界面的命令行程序,本文重点给大家介绍Qt 关于容器的遍历迭代器的使用问题小结,感兴趣的朋友一起看看吧
    2022-03-03
  • 深入了解C++优先队列(priority_queue)的使用方法

    深入了解C++优先队列(priority_queue)的使用方法

    在计算机科学中,优先队列是一种抽象数据类型,它与队列相似,但是每个元素都有一个相关的优先级。C++中的优先队列是一个容器适配器(container adapter),它提供了一种在元素之间维护优先级的方法。本文带你深入了解C++优先队列的使用方法,需要的可以参考下
    2023-05-05
  • C++取得当前时间的方法

    C++取得当前时间的方法

    这篇文章主要介绍了C++取得当前时间的方法,实例展示了通过系统函数获取当前时间的实现方法,非常简单易懂,需要的朋友可以参考下
    2014-10-10
  • C++存储持续性生命周期原理解析

    C++存储持续性生命周期原理解析

    这篇文章主要为大家介绍了C++存储持续性生命周期原理解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • C++学习笔记之浅谈异常处理

    C++学习笔记之浅谈异常处理

    C++ 提供了异常机制,让我们能够捕获运行时错误,本文就详细的介绍了C++异常处理入门,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • c++ bitset详解

    c++ bitset详解

    这篇文章主要介绍了C++ bitset用法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-08-08
  • 用C语言递归实现火车调度算法详解

    用C语言递归实现火车调度算法详解

    本文主要介绍了用C语言递归实现火车调度算法详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • C++ EasyX学习之鼠标操作详解

    C++ EasyX学习之鼠标操作详解

    EasyX是针对C/C++的图形库,可以帮助使用C/C++语言的程序员快速上手图形和游戏编程。本文将为大家详细讲讲EasyX的鼠标操作,需要的可以参考一下
    2022-07-07
  • C++大数模板(推荐)

    C++大数模板(推荐)

    本篇文章是对C++大数模板的程序代码进行了详细的分析介绍,需要的朋友参考下
    2013-05-05

最新评论