C++对象模型和this指针

本文详细介绍了C++中类的成员变量和成员函数的存储方式,强调只有非静态成员变量属于类的对象。讨论了空类和含有非静态成员变量的类在内存占用上的区别,以及静态成员变量和成员函数的存储位置。此外,重点阐述了this指针的作用,它是如何解决成员函数调用时的对象定位问题,并给出了实例演示this指针在解决命名冲突和链式编程中的应用。
摘要由CSDN通过智能技术生成

在C++中,类的成员变量和成员函数分开存储

类的成员变量


只有非静态成员变量才属于类的对象!!(静态成员变量、函数都不属于类的对象)

看下述代码段,在其中,说明了只有非静态成员变量才属于类的对象;静态成员函数、静态成员变量、以及成员函数都不属于类的对象

且在空的类当中,其所占内存空间为1个字节,目的是为了在内存空间中使得类的空间得到定位;

而一旦在类中,出现了非静态的成员变量,(假设为整形)那么此时类的大小为4字节。

class Person
{
	int m_A;//非静态成员变量
	static int m_B;

	void func()//非静态成员函数,也不属于任何对象
	{

	}

	static void func2()
	{

	}

};

int Person::m_B = 10;

void test01()
{
	Person p;

	//为什么空类的内存空间大小为1?
	//因为C++编译器会给每个空对象也分配一个字节空间,为了区分空对象占内存空间的位置
	//每个空对象也应该有一个独一无二的内存地址

	cout << "size of p = " << " " << sizeof(p) << endl;//空类的内存空间为:1

	//然后有整数型的成员变量后,打印结果为4;因为一旦有了成员变量后,就可以把区分的位置字节删除
	//在加上静态成员变量后,打印的结果仍然是4,所以静态成员变量不属于任何对象。
	//成员函数与成员变量是分开存储的,且非静态成员函数也是不属于任何类的
	//静态成员函数也是不属于任何类的

}

int main()
{
	test01();


	system("pause");
}

this指针

this指针的概念


首先提出问题,C++中,成员变量和成员函数是分开存储的
每一个非静态成员函数只会诞生一份函数实例,也就是说,多个同类型对象会共用一块代码
那么 这一块代码 如何区分哪个对象调用自己呢?
 
C++提供特殊的对象指针,this指针,解决上述问题
this指针指向被调用的成员函数所属的对象

this指针是隐含每一个非静态成员函数的一种指针!
this指针不需要定义,直接使用即可!


this指针的用途:


1. 当形参和成员变量同名时,可用this指针区分
2. 在类的非静态成员函数中返回对象本身,可使用return *this
 

然后用下述代码段来做一个案例:

首先从有参构造函数来说,成员变量的名称与构造函数形参的名称重复了;结合this指针特性:
this指针是隐含每一个非静态成员函数的一种指针!
this指针不需要定义,直接使用即可!

所以可以用this指针解决,方法如下代码:


class Person
{
public:
	Person(int age)//这些age是重复的,并没有将成员变量进行赋值
	{
		this->age = age;//this指针指向的是被调用的成员函数所属的对象
	}

	//如果是用Person来接收返回值,那么每次都会创建新的对象,依次进行拷贝并创建新的对象
	//引用实质上是指针,所以一直指向,值得以叠加,但是Person本身会反复创建对象,所以不可以叠加。
	Person& PersonAddAge(Person &p) {
		this->age += p.age; //(被调用函数的)自身的年龄+=传入对象年龄
		return *this;//返回的是被调用成员函数所属的对象(p2)
	}
	//如果返回对象本体,需要用引用的方式作一个返回!
	//如果是用Person来进行返回类型定义,就相当于重新创建了一次函数,无法起到叠加的效果(每次都会重新创建)

	int age;
};


//1. this解决名称冲突
void test01()
{
	Person p1(18);//this指针指向的是被调用的成员函数所属的对象,即p1
	cout << "p1年龄: " << p1.age;
}

//2. 返回对象本身,用*this
void test02()
{
	Person p2(10);

	Person p3(10);
	//链式编程思想
	p2.PersonAddAge(p3).PersonAddAge(p3).PersonAddAge(p3);//在p2内调用,将p3传递过去
	//想要多次叠加年龄,需要从函数入手;如果返回值为p2,那么就可以多次调用


	cout << "p2的年龄为 : " << p2.age << endl;
}

int main()
{
	test01();
	cout << endl;
	test02();

	system("pause");
}

然后,对于代码段中的链式编程思想:

由于我们在实际工程中,创建很多对象的情况下,有时需要对对象中的某些特定的成员变量叠加,如果按照常规写法,会有些麻烦;于是先创建一个空的(或者是现有的)对象,然后在类中书写

Person& PersonAddAge(Person &p)这样形式的函数;其好处在于:使用引用,避免空间浪费;同时由于返回类型为对象引用(指针);所以可以多次对对象中的成员函数进行调用(返回整体还是对象,整体再调用成员函数,再返回再调用。。。。)

所以就引出了链式编程方法;

通过上述的解释,也就可以理解:p2.PersonAddAge(p3).PersonAddAge(p3).PersonAddAge(p3);即在p2内调用,将p3传递过去,然后整体返回作为对象,然后对象再次调用成员函数;以此实现多次访问的目的;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值