C++中的static

简介:

C++中的static

1.过程中的中的static

静态全局变量(在全局变量前加static)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using  namespace  std;
void  fn();
 
static  int  n; //static globle var
 
int  main()
{
     n=20;
     cout<<n<<endl;
     fn();
}
 
void  fn()
{
     n++;
     cout<<n<<endl;
}

 

静态全局变量有以下特点:

  • 未经初始化的静态全局变量被程序自动初始化为0;
  • 静态全局变量在整个文件中都是可见的,而在文件之外是不可见的;

以上代码中,如果把static去掉,照样运行正常。的确,定义全局变量可以用在整个文件中共享,但定义全局变量还有以下好处:

  • 静态全局变量不能被其它文件所用,其它文件定义相同的名字不会发生冲突。

注意全局变量和全局静态变量的区别:

  • 全局变量不加static修饰,但全局变量默认是静态的,作用于整个工程,在一个文件中定义全局变量,在另一个文件中用extern 全局变量声明,就可以使用全局变量。
  • 全局静态变量显示用static修饰,但是他作用于它所在的文件中,对于其它文件不可引用,即使用extern也无法引用它。

 

静态局部变量(在一个局部变量前加static)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
using  namespace  std;
 
void  fn();
 
void  main()
{
     fn();
     fn();
     fn();
}
 
void  fn()
{
     static  int  n=10;
     cout<<n<<endl;
     n++;
}

 

通常局部变量在函数完毕后变会被释放,基值不在保存。但是我们如果需要在两次调用的时候保存变量的值,通常的方法定义一个全局变量来实现,但是这样一来,变量不在属于函数本身了,而属于整个文件,给维护带来很多问题。静态局部变量可以很好的解决这个问题。

静态局部变量保存的全局数据区,而不是保存在栈上,每次的值保存到下一次调用,直到下一次赋新值。

静态局部变量有以下特点:

  • 该变量在全局数据区分配内存;
  • 它在执行到该对象首次声明处被首次初始化,即以后调用函数不再初始化。
  • 它一般在声明处初使化,如果没有显示初始化,则被初始化为0。
  • 它始终驻留于程序中,直到程序结束运行。但其作用域为局部作用域,当定义它的函数或语句块结束时,其作用域随之结束

静态函数(在函数返回值前面加static)

说明:它与变通函数不同,它只能在声明它的文件中可见,不能被其它文件使用。

好处:

  • 不能被其它文件所用;
  • 其它文件中定义同名函数,不会发各冲突。

2.面向对象中的static关键字(类中的static)

静态数据成员:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
// static_class_data_member.cpp : 定义控制台应用程序的入口点。
//
 
#include "stdafx.h"
#include <iostream>
using  namespace  std;
 
class  Myclass
{
public :
     Myclass( int  a, int  b, int  c);
     void  GetSum();
private :
     int  a,b,c;
     static  int  Sum; //it's a static class data member
};
 
int  Myclass::Sum=0; //definition and initial the static class data member
Myclass::Myclass( int  a, int  b, int  c)
{
     this ->a=a;
     this ->b=b;
     this ->c=c;
     Sum+=a+b+c;
}
void  Myclass::GetSum()
{
     cout<< "Sum=" <<Sum<<endl;
}
int  _tmain( int  argc, _TCHAR* argv[])
{
     Myclass M(1,2,3);
     M.GetSum();
     Myclass N(4,5,6);
     N.GetSum();
     M.GetSum();
     return  0;
}

可以看出静态数据成员有以下特点:

  • 对于非静态数据成员,第一个类对象都有自己的一份拷贝。而静态类成员被当作是类的成员,无论这个对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类型所有对象共享访问。也就是说,静态数据成员间该类的所有对象所共有的,对于类的多个对象来说,静态数据礔 只分配一次内存,供所有对象共用,所以,静态数据成员产的值对每天个对象都是一样的,它的值可以更新。
  • 静态数据成员在全局数据区。静态数据成员在定义时要分配空间,所以不能在类声明中定义,在上例中,语句int Myclass::Sum=0;是定义静态数据成员。
  • 静态数据成员和普通数据成员一样,遵从public,protected,private访问规则。
  • 因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定类对象,在没有产生类对象的时候它的作用域就已经可见了,即在没有产生类实例的时候,我们就可以操作它。
  • 静态数据成员与一般的数据初使化不同,格式化为:
  • <数据类型><类名>::<成员名>=<值>
  • 类的静态数据成员访问有两种形式:
  • <类对象名>.<静态数据成员名>或<类类型名>::<静态数据成员>
  • 如果静态数据成员的访问权限允许的话(public),按上述格式引用静态数据成员。
  • 静态成员变量主要在各个对象都有相同的某项属性的时候。比如对于一个存款类,每一个实例的利息都是相同的,所以应该把利息设为存款类的静态数据成员。这有两个好处和:第一、不管定义多少个存款类对象,利息数据成员都共享分配在全局数据区内存,所以节省存储空间。第二,一但利息需要改变时,只要改变一次就行了。
  • 同全局变量相比,使用静态数据成员有两个优势:
  • 静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性。
  • 可以实现信息的隐藏。静态数据成员可以是private成员,而全局变量不能。

静态成员函数

与静态数据成员一样,静态成员函数不是专们为某一相类对象而服务的,而是为此类的全部对象所服务。它不与任意类对象所联系,所以它不具有this指针。从这个意义上讲,它无法访问非静态数据成员,也无法访问非静态成员函数,它只能调用其余的静态成员函数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
 
using  namespace  std;
 
class  Myclass
{
public :
     Myclass( int  a, int  b, int  c);
     static  void  GetSum(); //static class_member fun
private :
     int  a,b,c;
     static  int  Sum; //static class_member_data
};
 
int  Myclass::Sum=0; //definition and initialization
Myclass::Myclass( int  a, int  b, int  c)
{
     this ->a=a;
     this ->b=b;
     this ->c=c;
     Sum+=a+b+c; //非静态成员函数可以访问静态数据成员
}
 
void  Myclass::GetSum()
{
     cout<< "Sum" <<Sum<<endl;
}
 
int  main()
{
     Myclass M(1,2,3);
     M.GetSum();
     Myclass N(4,5,6);
     N.GetSum();
     Myclass::GetSum();
}

关于静态成员函数,有以下特点:

  • 出现在类体外的函数定义不能指定关键字static;
  • 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数。
  • 静态成员函数不能访问非静态函数和非静态数据成员。
  • 由于没有this指针的额外开销,因此静态成员函数与类全局函数相比速度会有少许增长。
  • 调用:<类名>::<静态成员函数名>(<参数表>)

作用:

static静态变量声明符。在声明它的程序块,子程序块或函数内部有效,值保持在整个程序期间分配存储品空间,编译器默认值0。

是c++中很常用的修饰符,它被用来控制变量的存储方式和可见性。

相关文章
|
3月前
|
存储 编译器 C语言
详解C/C++中的static和extern
本文详解了C/C++中`static`和`extern`关键字的用法和区别,通过具体代码示例说明了在不同情境下如何正确使用这两个关键字,以及`extern "C"`在C++中用于兼容C语言库的特殊作用。
103 4
详解C/C++中的static和extern
|
7月前
|
C++
C++当类模板遇到static
C++当类模板遇到static
|
2月前
|
存储 编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(一)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
1月前
|
存储 编译器 C++
【c++】类和对象(下)(取地址运算符重载、深究构造函数、类型转换、static修饰成员、友元、内部类、匿名对象)
本文介绍了C++中类和对象的高级特性,包括取地址运算符重载、构造函数的初始化列表、类型转换、static修饰成员、友元、内部类及匿名对象等内容。文章详细解释了每个概念的使用方法和注意事项,帮助读者深入了解C++面向对象编程的核心机制。
84 5
|
2月前
|
C语言 C++
C 语言的关键字 static 和 C++ 的关键字 static 有什么区别
在C语言中,`static`关键字主要用于变量声明,使得该变量的作用域被限制在其被声明的函数内部,且在整个程序运行期间保留其值。而在C++中,除了继承了C的特性外,`static`还可以用于类成员,使该成员被所有类实例共享,同时在类外进行初始化。这使得C++中的`static`具有更广泛的应用场景,不仅限于控制变量的作用域和生存期。
67 10
|
2月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
40 3
|
2月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
53 3
|
2月前
|
C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(二)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
2月前
|
编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(三)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
3月前
|
C++
C/C++静态链接pthread库的坑【-static -pthread】
C/C++静态链接pthread库的坑【-static -pthread】