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

类与对象的内存

空类的内存空间:

首先,一个开辟了但什么都不放置的类的大小是1,因为即使我们什么都不放置,系统还是会默认给这个类开辟一个独特的内存空间以区分不同的类,这个默认的空间大小就是1

具体我们可以用下面的代码来测试一下:

class Info
{
public:
	;
};

int main()
{
	Info P;
	cout << sizeof(P) << endl;
	return 0;
}

毫无疑问,最后得到的结果就是1:

成员属性与成员函数的空间:

在考虑成员属性和成员函数的内存大小之前,我们需要知道一个知识点:成员属性和成员函数是分开存储的。为什么呢?我们知道,成员属性是具体到一个特定的对象的性质,它可以用来区分对象,而成员函数是所有类的统一行为,它不属于某个对象;类似的,静态成员属性,静态成员函数都只有一份内存;

我们可以做个简单的测试:下面两组代码都是输出4,但是它们一个有成员函数,一个没有成员函数,由此可见,成员函数的内存分配与具体的每一个对象无关。

this指针

由上面知道,一个类里面的非静态成员函数是与对象无关,那么同一个函数怎么区分是被哪个对象调用呢?这里就要引入this指针,this指针是一个常指针,即this指针的指向不能被修改。this指针不是一个对象的一部分,它用于当非静态成员函数访问类中的非静态成员,这个this指针就用于找到这个特定的对象,换句话说,this指针指向这个调用非静态成员函数的对象

其次,我们要清楚,this指针不需要我们手动声明或者定义,它是系统自己定义的,我们使用时不需要声明或定义;

this指针的作用:

1.用于区分形参和成员变量名:

class Info
{
public:
	void func(int id)
	{
		//id = id;
		this->id = id;
	}
	void Show()
	{
		cout << id << endl;
	}
private:
	int id;
};


int main()
{
	Info StuA;
	StuA.func(10);
	StuA.Show();
	return 0;
}

2.用于返回类对象本身:


class Info
{
public:
	Info(int a)
	{
		id = a;
	}
	Info& func(Info& p)这里返回要返回引用,不能返回对象类型
	{
		this->id += p.id;
		return *this;//返回对象本身
	}
	int id;
};

​

注意:当函数返回值为类对象本身(即Info)时,这里返回的是另一个拷贝出来的与原对象属性一样的对象,本质上返回的是另一个对象!!!

 所以如果要多次返回同一个对象,需要返回引用类型才能保证每次调用的是同一个引用,而不是创建出来的多个相同属性的对象!!!

this为空指针情况:

如果我们创建一个不存在的对象,即创建一个类的指针,但是类的指针为空,此时如果我们访问这个类的成员函数,是可以访问到一些不涉及成员变量的成员函数,但是不能访问到一些与成员变量有关的成员函数。因为此时this为空,成员变量与具体的对象有关,而我们没有创造具体对象是无法访问到某些的成员函数的。

class Info
{
public:
	void print()
	{
		cout << "hello,world!" << endl;
	}
	void travel_ch()
	{
		if (this == NULL)//增加的判断,防止出现this为空
		{
			cout << "this = NULL" << endl;
			return;
		}
		cout << "ch=" << ch << endl;
	}
	char ch;
};

int main()
{
	Info* pointer=NULL;//不存在的对象
	pointer->print();
	pointer->travel_ch();
	return 0;
}

常函数与常对象

常函数:就是类里面的函数不能修改成员变量的特殊函数(除非成员变量前加关键字mutable),常函数本质上是限制了this指针,将this指针由 类名 *const this 修改为 const 类名 *const this,让其不能对指向的内容进行修改。常函数语法为:返回类型+函数名()+const

常对象:常对象就是在对象前加上const,常对象不能对成员变量进行修改(除非成员变量前加mutable关键字)并且常对象只能调用常函数(因为通过非常函数有可能改变成员变量)。常变量语法为:const+类名+变量名

class Info
{
public:
	void Read() const
	{
		//要修改常函数内部的成员变量,需要添加关键字mutable
		tel = 30;
		//常函数内部不能修改成员变量
		//id = 10;
	}
	void Write()
	{
		id = 20;
	}
	mutable int tel;
	int id;
};


int main()
{
	Info StuA;
	StuA.id = 20;
	//常对象,常对象也不能修改成员变量,并且常对象之能调用常函数
	const Info StuB;
	//StuB.id = 10;
	StuB.tel = 30;
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值