目录

一、静态属性

 总结:

二、静态方法

例题:


   由关键字static修饰类中成员,成为类的静态成员。类的静态成员为其所有对象共享,不管有多少对象,静态成员只有一份存于公用内存中。静态数据成员被当做该类类型的全局对象。我们不能把静态成员的初始化放置在类的定义中,但是可以在类的外部通过使用范围解析运算符 :: 来重新声明静态变量从而对它进行初始化。

一、静态属性

        在类的设计中,用关键字static修饰的数据成员为静态数据成员。有该类型实例化的所有对象,共享系统为静态成员分配一个存储空间。而这个存储空间是程序执行main函数之前分配的,在实例化对象不再为静态成员分配空间(静态成员数据不再对象空间中)

静态属性也是受类的访问权限控制的

1、设计静态数据成员的目的是信息共享,只会被初始化一次,于实例无关

示例:

class Circle {
private:
	static double pi;
	double rid;
public:
	Circle(double r=0.0):rid(r){}
	~Circle(){}
	double area()const
	{
		return pi * rid * rid;
	}
};
double Circle:: pi=3.14;
int main()
{
	cout << sizeof(Circle) << endl;
	Circle cir(12.23);
	size_t sz = sizeof(cir);
	cout << sz << endl;
	return 0;
}

 也就是说 static 并不占用Cricle的内存空间(栈区),他在全局数据区分配内存

注意:

        与全局变量相比,使用静态数据成员有两个优势:

  1. 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能性
  2. 可以实现信息隐藏,静态成员可以是private,而全局变量不能 

 2、静态数据是该类所有对象所共有的,可以提供同一类型的所有对象之间,信息共享或信息交换的一种方式

        静态数据成员属于整个类型,使用时可以用以下格式:

        类名::静态数据成员名或者 对象.静态数据成员名(前提是可以访问符为public)

示例:

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      static int objectCount;
      // 构造函数定义
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
         // 每次创建对象时增加 1
         objectCount++;
      }
      double Volume()
      {
         return length * breadth * height;
      }
   private:
      double length;     // 长度
      double breadth;    // 宽度
      double height;     // 高度
};
 
// 初始化类 Box 的静态成员
int Box::objectCount = 0;
 
int main(void)
{
   Box Box1(3.3, 1.2, 1.5);    // 声明 box1
   Box Box2(8.5, 6.0, 2.0);    // 声明 box2
 
   // 输出对象的总数
   cout << "Total objects: " << Box::objectCount << endl;
 
   return 0;
}

输出结果:

Constructor called.
Constructor called.
Total objects: 2

3、在类的成员函数中使用静态数据成员,静态数据成员没有this指针,this指针指向类的对象本身,而static静态成员函数不依赖对象调用,它不与任何的对象相联系,所以当然不需要this指针。

4、静态属性的类型是int,short,char等整型,并且是const,可以在类中直接初始化

class A{
public:
	static const int a=10;//想在类内定义 必须加const
	static void add2();
	static void add1()
	{
		++b;
		cout<<b<<endl;
	}
private:
	static int b;

};

int A:: b=20;
void A::add2()
{
	
	cout<<a<<endl;
}
int main()
{
	A::add2();
	A::add1();
}

 

 总结:

  1. 设计静态数据成员目的是信息共享,和信息交流
  2. 类的静态数据成员为所有类对象所共享,不属于某个具体的实例
  3. 类的静态数据成员必须在类外定义,定义时不添加static关键字,不能在构造函数的初始化列表中创建
  4. 类的静态数据成员类型是int,short,char ,longlong,并且是const,可以在类中直接初始化也可以在类外初始化
  5. 在类的成员函数中使用静态数据成员,静态数据成员之前没有this
  6. 当类的静态数据成员为公有时,可以在外部函数使用:类名::静态数据成员名或者对象.静态数据成员名
  7. 可以在类体中定义自身的静态类型对象

二、静态方法

  1. 如果把函数成员声明为静态的,就可以把函数与类的任何特定对象独立开来。静态成员函数即使在类对象不存在的情况下也能被调用,静态函数只要使用类名加范围解析运算符 :: 就可以访问。
  2. 静态成员函数只能访问静态成员数据、其他静态成员函数和类外部的其他函数。
  3. 静态成员函数有一个类范围,他们不能访问类的 this 指针。可以使用静态成员函数来判断类的某些对象是否已被创建。
  4. 静态成员函数在类内,类外具体定义实现,都是可以的

注意:

        静态成员函数没有this指针,因此在静态成员函数显式的使用this指针都将会导致编译时刻错误,试图访问隐式使用this指针所指向的非静态数据成员也会导致编译时刻错误

静态成员函数与普通成员函数的区别:

  • 静态成员函数没有 this 指针,只能访问静态成员(包括静态成员变量和静态成员函数)。
  • 普通成员函数有 this 指针,可以访问类中的任意成员;而静态成员函数没有 this 指针。

示例: 

#include <iostream>
 
using namespace std;
 
class Box
{
   public:
      static int objectCount;
      // 构造函数定义
      Box(double l=2.0, double b=2.0, double h=2.0)
      {
         cout <<"Constructor called." << endl;
         length = l;
         breadth = b;
         height = h;
         // 每次创建对象时增加 1
         objectCount++;
      }
      double Volume()
      {
         return length * breadth * height;
      }
      static int getCount()
      {
         return objectCount;
      }
   private:
      double length;     // 长度
      double breadth;    // 宽度
      double height;     // 高度
};
 
// 初始化类 Box 的静态成员
int Box::objectCount = 0;
 
int main(void)
{
  
   // 在创建对象之前输出对象的总数
   cout << "Inital Stage Count: " << Box::getCount() << endl;
 
   Box Box1(3.3, 1.2, 1.5);    // 声明 box1
   Box Box2(8.5, 6.0, 2.0);    // 声明 box2
 
   // 在创建对象之后输出对象的总数
   cout << "Final Stage Count: " << Box::getCount() << endl;
 
   return 0;
}

编译结果:

Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2

例题:

不能使用if,循环,公式,求n的累加

//使用静态数据成员,调用n次构造函数,产生n次累加
class ADD
{
private:
	static int a;
	static int b;
public:
	ADD() {
		a += b;
		b++;
	};
	int Getnumber()
	{
		return a;
	}

};
int ADD:: a=0;
int  ADD::b=1;
//三目运算符求解
int ADD1(int n)
{
	return n == 1 ? 1 : ADD1(n - 1) + n;
}
int main()
{
	ADD* x = new ADD[100];
	cout << x->Getnumber() << endl;
	cout << ADD1(100) << endl;
	return 0;
}

为什么static成员函数不能是const?

静态成员函数是属于某个类的,而不是某个对象。所以在类被定义的时候,在对象被定义之前就已经存在了,所以显然也可以看出他不是某个对象,但是const是用来修饰对象的,使对象保持不变,里面的数据成员保持不变,那么对于不是对象的static函数,就不可以用const修饰了。函数中的const其实就是用来修饰this指针的,意味this指向的内容不可变,static成员函数没有this,就不能使用const

C++ static 关键字 总结/ static全局变量和全局变量的区别    推荐阅读

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐