C++静态成员

文章讲述了静态成员变量和静态成员函数在C++中的应用,如何解决类对象间的数据共享问题,以及静态成员的访问规则。它强调了静态成员变量不占用对象存储空间,而是为整个类共享,并可通过类名或对象名调用静态成员函数。
摘要由CSDN通过智能技术生成
  • 静态成员变量
    • 不同对象间共享同一份数据
    • 存储在全局区,再编译阶段分配内存
    • 类内声明,类外初始化
  • 静态成员函数
    • 不同对象间共享同一函数
    • 静态成员函数只能访问静态成员变量

        数据共享包括很多种,有时候类的对象与对象之间也需要共享数据,静态成员是解决同一个类的不同对象之间数据和函数的共享问题。 

class Student {
	private:
		int id;
};

        简单设计一个学生类,如果要统计一个班级所有学生类的数目,这个数据应该怎么存放?我们可以在类外设计一个全局变量来存放总数,但这就不能实现数据的隐藏。如果类内增加一个数据成员用来存放总数,那么类中的数据成员在类的每个成员中都有副本,不仅会造成数据冗余,而且每个对象都分别维护一个”总数“,很容易造成各对象数据的不一致。这个”总数“是为类的所有成员所共同拥有的,应该声明为静态成员变量。 

静态成员变量  

 在类中声明静态成员变量的格式如下:

class 类名{
static <静态成员变量声明>;
};

        类中声明的静态成员变量仅仅是引用声明,必须在命名空间作用域的某个地方使用类名限定定义声明,这是也可以进行初始化。与类的一般成员变量不同,静态成员变量需要在类定义之外再进行定义 ,因为需要以这种方式专门为它们分配空间。非静态成员变量的数据空间是与它们所属对象的空间同时分配的。一般在类的实现部分完成静态对象成员的初始化。静态成员定义及初始化格式如下:

类名::静态成员变量标识符=初始化;

        静态成员是类的所有对象共享的成员,而不是某个对象本身的成员,他在对象中不占存储空间。在使用时,可以通过对象引用类的静态成员,也可以不定义对象,通过类直接引用成员。 

         Studet表示学生类,在Studet类中引入静态成员变量count用来统计Studet类对象个数。

#include <iostream>
using namespace std;

class Student {
	private:
		int m_id;
		static int count;

	public:
		Student(int id): m_id(id) {
			count++;
		};
		
		//输出学生信息
		void showInfo() {cout << "ID:" << m_id << endl;};
		
		//学生总人数		
		void showCount() {cout << "总人数:" << count << endl;};	

        //输出学生总人数	静态成员函数
		static void showcount() {cout << "静态成员函数输出总人数:" << count << endl;};			
};

int Student::count = 0;		//静态成员变量初始化

int main() {
	Student stu1(101);
	stu1.showInfo();
	Student stu2(102);
	stu2.showInfo();
	cout << "stu1的count输出:";
	stu1.showCount();
	cout << "stu2的count输出:";
	stu2.showCount();
	return 0;
}

说明: 1、静态成员count的定义和初始化必须在类外进行,初始化时引用的方法要注意两点:(1)必须用类名来引用;(2)虽然静态成员变量在类中声明是私有的,在这里却可以直接初始化。除了定义初始化的时候,在其他地方,例如,在主函数中就不允许直接访问。

静态成员函数 

         在上述中,函数shoeCount是专门用来输出静态成员count的。count是类中的私有成员,如果需要查看count的值,需要调用类的共有接口shoeCount。在所有对象声明之前,系统中对象个数为0,可否通过showCount将这个值输出呢?由于此时系统中还买有任何对象,无法通过对象来调用showCount,由于count是整个类共有的,不属于某一个对象,因此,我们希望对count的访问也可以不通过对象,而直接通过类名来访问。

int main() {
	cout << "类名调用:";
	Student::showcount();
	Student stu1(101);
	stu1.showInfo();
	Student stu2(102);
	stu2.showInfo();
	cout << "对象stu1调用:";
	stu1.showcount();
	cout << "对象stu2调用:";
	stu2.showcount();
	return 0;
}

 

        如果我们使用类名Student直接调用showCount函数,那么编译时会报错,语句出错,提示对普通函数showCount的调用必须通过对象名。静态成员函数就像静态成员变量一样,静态成员属于整个类,有同一个类的所有对象共同拥有,为这些对象共享。静态成员函数可以由类直接调用,不需要通过类定义对象后在调用,但这不意味着静态成员函数的调用必须通过类名,通过对象名也是可以的。

静态成员访问

         类中非静态成员只能通过对象名调用,而静态成员包括静态成员变量和静态成员函数,可以在类外通过类名和对象名来调用。但要习惯使用类名调用静态成员,因为即使是通过对象名调用静态成员,实质上也是通过对象的类型信息确定调用类的静态成员,与具体对象没有任何关系。 

        在一般情况下,类中静态成员函数主要用于访问同一个类中的静态数据成员,而不能访问类中的非静态成员变量。因为静态成员函数实质上并不是由某个具体对象调用的,所以不能隐含地调用对象访问类中的非静态成员。

         在上述实例中我们不能在静态成员函数showconut中访问本类的非静态成员m_id。如果一定要在静态成员函数中访问非静态成员变量,可以显示通过对象类调用。

//静态成员函数访问非静态成员变量
static void show(const Student &stu) {cout << "id:" << stu.m_id << "\t总人数:" << count << endl;};
int main() {
	Student stu1(101);
	stu1.show(stu1);
	Student stu2(102);
	stu2.show(stu2);
	return 0;
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

起风了呦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值