static作用解析(以c++为例)

前言

static是存储方式的一种,在c++中static有两种用法:

  • 面向过程程序设计
  • 面向对象程序色设计

其实概括起来,static的作用就是使被它所修饰的词的生存期变长,还有就是私密性这里后面再介绍。
然后对于这个还要了解一下内存分布情况:

  • 栈区: 由编译器自动分配释放,像局部变量,函数参数,都是在栈区。会随着作用于退出而释放空间。
  • 堆区:程序员分配并释放的区域,像malloc©,new(c++)所申请的空间就是在堆区。
  • 全局数据区(静态区):全局变量和静态便令的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。程序结束释放。
  • 代码区,用于储存代码。

面向过程程序设计

静态变量

在用static修饰变量时,此变量有一下特性:

  • 该变量保存在静态存储区,在程序结束时才被销毁。
  • 如果该变量没有进行赋予初始值,被static修饰时会有初始值0。
//第一个文件
#include<iostream.h>
static int n;
int main(){
	n=5;
	while(n--)
	cout<<n--<<endl;
}

//第二个文件
#include<iostream.h>
extern int n;//extern 的意思是引用外面文件中的变量。
int main(){
	n=5;
	while(n--)
	cout<<n--<<endl;
}

这样第二个文件运行时会出错,但是如果把第一个文件中n的定义改为int n,这样就可以运行了。
这里呢,定义静态全局变量的好处就是:静态全局变量不能被其他文件所用,而且其他文件中定义相同名字的变量会相互不影响。
然后再看看两个程序:

#include <iostream.h>
void f();
void g();
int main()
{
         f();
         g();
         f();
         g();
}
void f()
{
         static n=10;
         cout<<"f="<<n<<endl;
         n++;
}
void f()
{
         j=10;
         cout<<"g="<<j<<endl;
         j++;
}
//输出:
f=10;
g=10;
f=11;
g=10;

静态函数的作用和静态变量的作用差别不大。在定义之后也不能被外部文件通过extern进行引用。

面向对象编程程序设计

静态数据成员

  • 静态数据成员脱离具体对象而独立存在,其存储空间是独立分配的,所以就算类没有任何对象的时候它都可以访问。
  • 静态数据成员是一种特殊的数据成员,它为类属性,而不是某个对象单独的属性,这里是因为它保存在全局变量区,然后生存期比实体都长,所以这是类的属性。
  • 在类中只能进行声明,不能定义。定义只能在外面进行。
  • 静态数据成员可以作为成员函数的默认形参,而普通数据成员则不可以
class Test{
public:
    static int a;
    int b;
    void fun_1(int i = a);//正确
    void fun_2(int i = b);//报错
    };
  • 静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的 指针或引用
class Test{
public:
	static Test a;//正确
	Test b;//报错
	Test *pTest;//正确
	Test &m_Test;//正确
	static Test *pStaticObject;//正确
};

static修饰后对比:

#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;
};
int Myclass::Sum=0;
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;
}
void main()
{
         Myclass M(1,2,3);
         M.GetSum();
         Myclass N(4,5,6);
         N.GetSum();
         M.GetSum();
}
/*输出结果:
Sum=6
Sum=21
Sum=21
如果把static去掉的话。
输出结果会是:
Sum=6
Sum=15
Sum=6*/

静态数据函数

特点:

  • 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数
  • 非静态成员函数可以任意地访问静态成员函数和静态数据成员
  • 静态成员函数不能访问非静态成员函数和非静态数据成员
  • 调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以用类名::函数名调用(因为他本来就是属于类的,用类名调用很正常)

这里有个疑问,为什么静态成员函数不能访问非静态函数和成员,但时非静态可以访问静态。因为静态成员函数是属于类的,所以这个函数不知道到底有多少个对象,所以就无法访问。然后反过来,创建的对象对类是知道的,就可以直接使用类里面的函数。所以会有这个结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值