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

首先了解一下内存的分布图:

代码区
全局数据区
堆区
栈区

代码区:存储代码
全局数据区:static 数据, 全局变量, const常量
堆区:由程序员自己new出来的动态数据, 需要手动释放。若忘记释放,会造成内存泄漏,则程序结束时会由操作系统回收。
栈区:函数内部变量,由IDE自动分配,结束时自动释放。

后续可以再仔细研究一下堆区和栈区的区别,这里先不讨论。

首先总结static全局变量和全局变量的区别:

  • 两者的存储都是在全局数据区,存储方式相同

  • 普通的全局变量,它作用在整个源程序,如果一个源程序有多个源文件,那这个全局变量在所有源文件中都有效

  • “”static”全局变量限制了它的作用域只在定义该变量的源文件内, 只能此文件的函数公用,其他的源文件不能使用该static全局变量,可以避免在其他源文件中使用而引起错误,其他文件还能命名相同名字的变量,不会发生命名冲突

再说一下static局部变量的用途与局部变量的区别:

先举个小栗子:
void fun()
{
static int i=1; // int i
count<<i<<endl;
i++;
}
void main()
{
fun();
fun();
}
正常情况下 函数内定义的局部变量,每当程序运行到这个语句时,会给这个变量分配内存到栈区,但当程序退出函数体时,系统就会自动回收栈内存,这个局部变量也就失效了。
而静态局部变量就能解决这个问题,它的内存保存在全局区,即使程序退出函数体,它也不会失效,它存储的值会 一直保存到直到下一次赋值

总结一下:

  • static局部变量在首次声明时被初始化,内存在全局数据区,之后再调用也不会初始化或重新分配内存。

  • static局部变量一般在声明时就赋值初始化,否则程序会默认初始为0。

  • static局部变量驻留在全局数据区,直到程序结束,但它的作用域还是局部作用域,当定义它的函数体结束时,作用域也就结束了。

static静态函数

static void func()//声明静态函数
与static全局变量相似,static函数只在当前源文件中可用,不能被其他文件所用,其他源文件也能定义相同名字函数,不会冲突

类中的static

举个栗子:
clase Myclass
{
private:
int a, b;
static int count;
public:
Myclass(int a,int b);
void Getcount();
}
int Myclass:: count =0;
Myclass::Myclass(int a,int b )
{
this->a = a;
this->b = b;
count += a+b;
}
void Myclass:Getcount()
{
cout<<“count =”<<cout<<endl;
}
int main()
{
Myclass A(1,2);
A.Getcount();
Myclass B(3,4);
B.Getcount();
A.Getcount();
B.Getcount();
return 0;
}
总结一下:static数据成员的特点:

  • 通常,每次类分配一个对象。它的数据都会拷贝,但是static数据成员无论类的对象定义了多少个,它只拷贝了一份,由声明它的类的所有对象共用。也就是说不论是对象A,还是对象B 调用static数据成员变量,都是一样的。
  • static数据成员不能定义在类中,需要在类外定义 int Myclass:: count =0;
  • static数据成员也遵从private,public,protected访问规则
  • 类的static成员有两种访问形式:(前提是public权限)
    <类对象名>.<静态数据成员名> 或 <类类型名>::<静态数据成员名>

static成员函数:

static成员函数不是为类的某一个对象服务,而是为类的所有所服务。
其实普通的成员函数都隐藏了一个this指针,它指向类对象本身,但通常情况下this是缺省的。而static成员函数并不属于某个具体的对象,所有它没有this指针。 也就是它无法访问类对象的普通成员函数,或普通数据成员,它只能调用static函数或数据成员。

举个栗子:
clase Myclass
{
private:
int a, b;
static int count; //静态数据成员
public:
Myclass(int a,int b);
static void Getcount(); //声明静态成员函数
}
int Myclass:: count =0;//初始化静态数据成员
Myclass::Myclass(int a,int b )
{
this->a = a;
this->b = b;
count += a+b;
}
void Myclass:Getcount()
{
// cout<<a<<endl ; //无法访问普通数据成员
cout<<“count =”<<cout<<endl;
}
int main()
{
Myclass A(1,2);
A.Getcount();
Myclass B(3,4);
B.Getcount();
A.Getcount();
Myclass::Getcount();
return 0;
}
总结一下static成员函数特点:

  • “”static“”成员可以相互访问,比如static成员函数或static静态数据成员
  • 普通成员函数可以访问静态成员函数和静态数据成员
  • 静态成员函数无法访问普通的成员函数或数据成员
  • 类外的函数定义不能使用static关键字
  • 因为没有this指针,所以static成员函数会比类的全局函数速度快一点点
  • 调用静态成员函数,可以用成员访问操作符(.)和(->)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式:
    <类名>::<静态成员函数名>(<参数表>) 调用类的静态成员函数。
  • 11
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值