C++学习之对象特性:静态成员、this指针

静态成员

静态成员变量:

所有对象共享同一份数据,在编译阶段分配内存(全局区),类内声明,类外初始化,也有访问权限。

class Person
{
public:
	static int P_a;//类内声明
};
int Person::P_a = 100;//类外初始化

共享数据:

void test()
{
	Person p1;
	cout << "p1.P_a=" << p1.P_a << endl;
	Person p2;
	p2.P_a = 200;
	cout << "p1.P_a=" << p1.P_a << endl;
}
int main()
{
	test();
	system("pause");
}

在这里插入图片描述
上述访问静态成员变量是采用通过对象进行访问
也可以通类名进行访问:

cout << "P_a=" << Person::P_a << endl;

代码运行前:代码区、全局区,代码运行后:堆区、栈区

静态成员函数:

所有对象共享同一个函数,静态成员函数只能访问静态成员变量吗,同上也有两种访问方式:对象、类名,也有访问权限。

class Person
{
public:
	static int P_a;//类内声明
	int P_b;
	static void func()
	{
		P_a = 0;//静态成员函数可以访问静态成员变量
		//P_b = 0;//不可以访问非静态成员变量,编译器无法确定是哪个对象的P_b
		cout << "静态成员函数" << endl;
	}
};
void test2()
{
	Person p1;
	p1.func();//通过对象进行访问
	Person::func();//通过类名进行访问
}

this指针知识:

只有非静态成员变量属于类的对象,静态成员变量,成员函数,静态成员函数均不属于类的对象。空对象占用内存空间为1,是为了区分空对象占内存的位置,每个空对象也应该有自己独有的内存地址。
就非静态成员函数而言,只有一个,怎么分配给多个对象呢,通过this指针,this指针是隐含每一个非静态成员函数内的一种指针,不需要定义直接使用即可。

this指针作用

1、解决名称冲突

#include <iostream>
#include<string>
using namespace std;
class Person
{
public:
	int age;
	Person(int age) //如果构造函数的形参和成员变量名称一致时就会出现错误,导致没有传入任何参数。
	{
		age = age;

	}
};
void test()
{
	Person p1(18);
	cout << "p1的年龄:" << p1.age << endl;
}
int main()
{
	test();
	system("pause");
}

在这里插入图片描述
解决方法:
(1)使用不同的名称,规范名称

class Person
{
public:
	int m_age;
	Person(int age)
	{
		m_age = age;

	}
};

(2)使用this指针

class Person
{
public:
	int age;
	Person(int age)
	{
		this->age = age;//this指针指向被调用的成员函数所属的对象

	}
};

2、返回对象本身用*this

class Person
{
public:
	int age;
	Person(int age)
	{
		this->age = age;
	}
	void add(const Person& a)
	{
		this->age = this->age + a.age;
	}
};
void test()
{
	Person p1(18);
	cout << "p1的年龄:" << p1.age<< endl;
	Person p2(2);
	cout << "p2的年龄:" << p2.age << endl;
	p2.add(p1);
	cout << "p2的年龄:" << p2.age << endl;
}

需求:要求p2的年龄加上p1的年龄多次,不能直接这样写:

p2.add(p1).add(p1).add(p1).add(p1);

因为只有当add()这个函数返回值是p2时才能像这么写

class Person
{
public:
	int age;
	Person(int age)
	{
		this->age = age;
	}
	Person & add(const Person& a) //引用是地址传递
	{
		this->age = this->age + a.age;
		return *this;//this是指向p2的指针,而*this指向的就是p2这个对象本身
	}
};
void test()
{
	Person p1(18);
	cout << "p1的年龄:" << p1.age<< endl;
	Person p2(2);
	cout << "p2的年龄:" << p2.age << endl;
	p2.add(p1).add(p1).add(p1).add(p1);//链式编程思想
	cout << "p2的年龄:" << p2.age << endl;
}

如果不采用引用方式,而采用值方式返回

	Person  add(const Person& a) //引用是地址传递
	{
		this->age = this->age + a.age;
		return *this;//this是指向p2的指针,而*this指向的就是p2这个对象本身
	}

在这里插入图片描述
因为之前构造函数部分讲过,以值方式返回局部对象会调用拷贝构造函数,会创建一个新的对象,新的对象的age会变化,但p2这个对象的age只会加一次。

当空指针访问成员函数

class person
{
public:
	int m_age;
	void showage()
	{
		cout << "age=" << m_age << endl;//当调用属性时,默认是
		//cout<<"age="<<this->m_age<<endl;this自动会调用
	}
};
void test1()
{
	person* p = NULL;//但当定义空指针时,this没有指向一个确切的对象,是空,this->m_age就会错
	p->showage();
}

为了系统不崩溃,可以:

class person
{
public:
	int m_age;
	void showage()
	{
		if(this == NULL)
		{
			return;
		}
		cout << "age=" << m_age << endl;
	}
};

const修饰成员函数

class person
{
public:
	int m_age;
	mutable int b;
	void showage1()
	{
		m_age=100;//等价于this->m_age=100;  this指针的本质是指针常量,指针的
		//指向是不可以修改的
	}
	//若同时不想修改成员变量的值
	void showage2()const//在成员函数后面加const,修饰的是this指针,让指针指向的值也不可以修改
	{
		//在这种函数中一般的变量不允许修改
		//特殊的:mutable关键字修饰的变量
		b = 2;
	}
};
void test2()
{
	const person p;//常对象,在对象前加const,变为常对象
	//属性不允许修改,除了mutable修饰的属性
	//常对象只允许调用常函数
}
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值