C++之static

     

目录

一、静态属性

 总结:

二、静态方法

例题:


   由关键字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全局变量和全局变量的区别    推荐阅读

  • 5
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
C++中,`static`是一个关键字,可以用于修饰变量、函数和类。它具有不同的含义,取决于它所修饰的内容。 1. 静态变量(Static Variables):在函数内部使用`static`修饰的变量称为静态变量。静态变量在程序的生命周期中只被初始化一次,并且在函数调用之间保持其值。静态变量存储在静态存储区,而不是堆栈中。可以通过函数名和作用域解析运算符来访问静态变量。 ```cpp void foo() { static int counter = 0; // 静态变量 counter++; cout << "Counter: " << counter << endl; } int main() { foo(); // 输出: Counter: 1 foo(); // 输出: Counter: 2 return 0; } ``` 2. 静态函数(Static Functions):在类中使用`static`修饰的成员函数称为静态函数。静态函数不依赖于任何特定的对象,可以直接通过类名进行调用。它们不能访问非静态成员变量,只能访问其他静态成员(包括静态变量和静态函数)。 ```cpp class MyClass { public: static void staticFunc() { cout << "This is a static function" << endl; } }; int main() { MyClass::staticFunc(); // 输出: This is a static function return 0; } ``` 3. 静态数据成员(Static Data Members):在类中使用`static`修饰的成员变量称为静态数据成员。静态数据成员属于类本身,而不是类的实例。它们在程序的生命周期中只有一个副本,并且可以被类的所有对象共享。静态数据成员必须在类外部进行定义和初始化。 ```cpp class MyClass { public: static int staticVar; }; int MyClass::staticVar = 10; // 定义和初始化静态数据成员 int main() { cout << MyClass::staticVar << endl; // 输出: 10 return 0; } ``` 使用`static`关键字可以有效地控制变量、函数和类的作用范围和生命周期,并且具有一些特殊的用途,例如实现单例模式或在类中共享数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ryan小小锅

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

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

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

打赏作者

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

抵扣说明:

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

余额充值