静态成员和静态函数

本文详细介绍了C++中的静态成员,包括静态数据成员和静态成员函数。静态成员允许类的不同对象共享同一份数据,不占用每个对象的内存。静态数据成员在类外定义并初始化,静态成员函数不能访问非静态成员。文中给出了多个示例,展示了静态成员的使用方法及其在对象计数、数据共享等方面的应用。
摘要由CSDN通过智能技术生成

静态成员

类中可以定义静态的数据成员,从而实现同类的多个对象之间的数据共享。
使用类的静态成员的优点是:
1)静态成员的名字是在类的作用域中,因此可以避免与其他类的成员或全局对象名字冲突。
2)静态成员可以实施封装,可以是私有成员,而全局对象不可以。
3)静态成员是特定类关联的,结构清晰。
例1:

class employee{
private:
        int empNo;
        int id; 
        char *name;
        static int count;//静态数据成员 
}; 

例2:

class Data{
	public:
		static int count;//静态数据成员
		int maxlevel;//非静态共有数据成员
		Data(int i=0){.....,count++;} //构造函数
		//即每次构造一个对象,构造函数都会被调用一次,则每次
		//count的值加一,因此计算出对象的数量
		private:
		int level;//非静态私有数据成员 
}; 
int Data::count=0;//静态成员定义且初始化

count设计的目的是计数Data类总共有多少个实例化的对象
说明:
1)通常,非静态数据成员存在于类类型的每个对象中,静态数据成员则独立于该类的任何对象,在所有对象之外单独开辟空间存储。在为对象所分配的空间中不包括静态数据成员所占的空间。
2)如果只声明了类而未定义对象,则类的非静态数据成员是不占存储空间的,只有在定义对象时,才为对象的数据成员分配空间。但是只要在类中定义了静态数据成员,即使不定义任何对象,也为静态数据成员分配空间,它可以在尚未建立对象时就被引用。
3)访问静态成员时,同时需要遵守公有私有的访问规则
4)静态数据成员必须在类外部定义一次(仅有一次),静态成员不能通过类构造函数进行初始化,而是在类外定义时进行初始化。
定义静态数据成员的方式为:
数据成员类型 类名::静态数据成员名=初始化的值;
5)静态数据成员可用作默认实参,非静态数据成员不能用作默认实参,因为它的值不能独立于所属的对象而使用。
6)有了静态数据成员,各个对象之间实现了数据共享,因此可以不使用全局变量。

静态成员函数

例3:

#include<bits/stdc++.h>
using namespace std; 
class test{
	private:
		int x;
		int y;
		public:
			static int num;
			static int Getnum()
			{
				x+=5;//错误,静态成员函数不能调用非静态数据成员
				num+=15;
				return num; 
			}
};
int test::num=10;
int main(){
	test a;
	cout<<test::num<<endl;//输出10 
	test::num=20;
	cout<<test::num<<endl;//输出20 
	cout<<test::Getnum()<<endl;//输出35 
	cout<<a.Getnum()<<endl;//输出50 
	return 0; 
}
(静态成员函数不能调用非静态数据成员)

和静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分。如果要在类外调用公有的静态成员函数,可以类作用域运算符(::)和通过对象名调用静态成员函数,例如:

cout<<Data::getcount()<<'\t'<<d.getcount();

静态成员函数与非静态成员函数的根本区别是:非静态成员函数有this 指针,而静态成员函数没有因此,静态成员函数不能访问本类中的非静态成员。
静态成员函数就是专门为了访问静态数据成员的。
静态成员函数不能被声明为const

例4:

#include<iostream>
using namespace std;
class CTest{
	public:
		CTest(){s_total++;id=s_total;cout<<"构造"<<endl; }
		~CTest(){s_total--;cout<<"析构"<<id<<" ";}
		static int gettotal(){return s_total; }
		private:
			static int s_total;
			int id;
};
int CTest::s_total=0;
int main()
{
	CTest a,b,c;
	CTest *p=new CTest;
	cout<<"合计="<<CTest::gettotal()<<" ";
	delete p;
	cout<<"合计="<<CTest::gettotal()<<" ";
	return 0;
}
//运行结果
构造
构造
构造
构造
合计=4 析构4 合计=3 析构3 析构2 析构1

例5

class Test{
	public:
		void init(){}
		static void output(){}
};
int main()
{
	Test::init();//错误,因为不能通过类名来调用类的非静态成员函数
	return 0; 
}
class Test{
	public:
		void init(){}
		static void output(){}
};
int main()
{
	Test t;
	t.init();
	t.output();//正确,类的对象可以使用静态成员函数和非静态成员函数 
	return 0; 
}

例6:

class Test{
	public:
	    Test(){m++;}
	    ~Test(){m--;}
		static void output(){cout<<m<<endl;}
		privatestatic int m; 
};
int main()
{
	Test t;
	t.output();
	return 0; 
}

*程序错误,因为类的静态数据成员在使用前必须先初始化,如果在main函数之前加上int Test::m=0;就不会出现错误,且程序运行结果为1

代码小白,若有错误,欢迎指正

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值