自学C++(3)

目录

1、各种情况下一个对象所占存储空间的变化

2、this指针

3、空指针访问成员函数

4、类中的const修饰


1、各种情况下一个对象所占存储空间的变化

(1)如果class  Person里不含任何东西,此时新建一个Person  p对象,则p所占空间是1个字节;

(2)如果class  Person里包含一个int m,则p占4个字节;

(3)如果class  Person里包含一个static int m,由于static类型是存储在全局中,因此不占某个对象的空间;

(4)如果class  Person里包含一个函数void func(){ },则仍然只占1个字节,static void func()同理

由上面可知,所有成员函数都是分开存储的,不记在某个对象的存储空间中,只有成员变量是算在对象的存储空间里的。

2、this指针

this有两种必须使用的情况:

(1)当成员函数的形参和成员变量同名时,必须用this->age的形式指代当前对象的age变量;

(2)当非静态的成员函数的返回值是对象本身时,要return* this。这种情况一般用于实现链式编程。

静态成员函数没有this指针,因为所有同类型的对象都使用同一个静态成员函数,不需要通过this指针来区别是哪个对象在调用这个函数

先看第一种情况:

如果不用this指针,则会出现错误:

 再看第二种情况:

 为了能链式调用,则必须让p1.AddAge(10)的返回值是一个Person类型

下面是修改后的AddAge函数,里面存在错误

最容易发现的错误是返回值。this是一个指针,它定义的方式为Person* const this(const表示this指针无法改变指向),这是编译器隐式定义给Person类的。因此,return this返回的是一个地址,它的类型不是Person,这里应该改成return *this。

修改之后成功运行,但是结果才20,理论值应该是40

这是另一个不容易发现的错误: 上面这个函数返回的虽然是一个Person类型的对象,但是通过值传递的方式返回。以值的方式返回局部对象会调用拷贝构造函数,从而生成新的匿名变量p2,之后就是调用p2.AddAge(10).AddAge(10),再然后是p3.AddAge(10), 虽然最后p4 = 40, 但是没有影响p2里面的age属性

要修改p2里的age,则需要返回引用类型,如下图:

 源代码放在下面

#include<iostream>
using namespace std;

class Person{
	public:
	Person(int age){
		this->age=age;
	}
	Person& AddAge(int age){
		this->age+=age;
		return *this;
	}
	int age;
};

int main()
{
	Person p1(10);
	p1.AddAge(10).AddAge(10).AddAge(10);
	cout<<p1.age<<endl;
	return 0;
}

3、空指针访问成员函数

#include<iostream>
using namespace std;

class Person{
	public:
	void showClassName()
	{
		cout<<"Person"<<endl;
	}
	void showAge()
	{
		cout<<age<<endl;
	}
	int age;
};

int main()
{
	Person p1=NULL;
	p1.showCLassName();
	p1.showAge();
	return 0;
}

这里将p1定义为空,则p1的this指针也指向空, 由于成员函数里的age在编译后默认变成

this->age,空指针没法找到age,因此函数showAge会报错无法运行。不过showClassName由于没有用到this指针,可以运行。虽然在devC++中只是warning,可以运行,但是其它一些编译器则无法运行。

4、类中的const修饰

 

 这里const实际上是修饰的this指针,原来this指针是这么定义的:Person* const this,上面的const让它变成了:const Person* const this,意味着this指针指向不变,它指向的内容也不改变。

给height变量前加上mutable,则它可以在常函数、常对象中被修改。

 在main函数里定义一个常对象,下图可见无法修改这个对象的age,但是可以修改常对象的mutable变量。同时,常对象也无法调用常函数以外的成员函数,这是因为:非常函数的成员函数可以对这个对象的所有实例变量进行修改,如果常对象可以调用非常函数的话,容易造成误操作,不利于安全性。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值