C/C++中static关键字用法总结

发布于:2024-04-05 ⋅ 阅读:(137) ⋅ 点赞:(0)

C++基础专栏:http://t.csdnimg.cn/4FdOH

目录

1.引言

2.静态局部变量

3.静态全局变量

4.静态函数

5.静态成员变量

6.静态成员函数

7.总结


1.引言

        在面试的过程,面试官经常都会问到static关键字有哪些用法?在C/C++中各有些什么作用?今天就在这里我们好好的总结一下static的全方位用法。

2.静态局部变量

        局部变量也就是定义在函数内部的变量,函数局部变量存放在栈区,该变量的生命周期由所在 {} 决定,进入 {} 作用范围而分配内存空间,退出 {} 作用范围而释放内存空间。在局部变量的前面加上static,变成静态局部变量,即使多次调用该函数,静态变量的空间也只分配一次。

C/C++中{}的用法总结(全)_c++ {}-CSDN博客

        定义在函数体内的变量加上static修饰符,它的存在意义是随着第一次函数的调用而初始化,但却不随着函数的调用结束而销毁。因此静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。示例如下:

#include <iostream>
using namespace std;

void test(void)
{
	int a = 1; // 局部变量
	static int b = 10; //静态局部变量

	a++;
	b++;
	cout << "a:" << a << ", b: " << b << endl;
}
int main()
{
	test(); //输出: a=1,b=11
	test();  //输出: a=1,b=12
	test();  //输出: a=1,b=13
	test();  //输出: a=1,b=14
	return 0;
}

3.静态全局变量

        全局变量的空间会在程序的生命周期内分配,在全局变量的前面加上static,变成静态全局变量。

        静态全局变量在全局数据区分配内存,那它和全局变量有啥区别呢?
        全局变量不但在本文件中可以被访问,在其他文件中同样可以访问。写代码时很容易在不同文件定义相同名字的全局变量,这就会引发冲突。而静态全局变量只能在声明它的整个文件可见,限制了该变量的访问范围。同样的,静态全局函数,在全局函数前加上static,表示只能在声明文件中被访问。

        示例:变量g_nTotalCount在static.cpp中定义为静态全局变量,因此无法在main.cpp中使用,运行会提示 “无法解析的外部符号”

//static.pp
#include <iostream>
#include  "static.h"
using namespace std;

static int g_nTotalCount = 22222; //静态全局变量,要想在main.cpp中使用,需定义为全局变量
//int g_nTotalCount = 22222; 
 void func(void)
 {
	 int x= 11;
	 cout << "x:" << x << endl;
 }
//static.h
#include <iostream>

void func(void);
//main.cpp
#include <iostream>
#include "static.h"
using namespace std;

int b = 2425; //全局变量

int main()
{
	extern int g_nTotalCount; //申明静态全局变量,运行失败,想用g_nTotalCount,则g_nTotalCount需定义为全局变量,而不是静态全局变量
	
	cout << "g_nTotalCount: " << g_nTotalCount << endl;

	func();

	return 0;
}

想使用static.cpp中的全局变量g_nTotalCount,则需要定义为全局变量,而不是静态全局变量。

4.静态函数

        在普通函数定义前加上修饰符static就是静态函数,作用和静态全局变量类似;函数的定义和生命在默认状态下都是extern的,但静态函数只是在申明他的文件当中可见,不能被其余文件所用。

5.静态成员变量

        一个类可以定义多个对象,每个对象都会对类中的普通成员变量进行空间分配,这些变量只由它所在对象使用。
        静态成员变量是该类的所有对象所共有的。对于普通成员变量,每个类对象都有自己的一份拷贝,而静态成员变量整个类就一份,静态成员变量只分配一次内存,类的所有对象都共享这个变量,不属于任何一个类,不需要对象就可以访问。
        静态成员变量不属于特定的对象,不会占用对象的内存,必须在类的外面进行初始化。对象的内存中只包括普通成员变量,注意不包括任何成员函数。sizeof(类名) 不会计算静态成员变量和成员函数。
        普通成员变量随这对象的产生而产生,静态成员变量随着类的产生而产生,所以静态成员变量不能由构造函数初始化,即使没有对象,也可以访问静态全局变量。

        示例如下:

#include <iostream>
#include <string.h>
using namespace std;

class MyTest
{
public:
   static int m_x; //声明静态成员变量
};
int MyTest::m_x = 3242234; //定义并初始化静态成员变量

int main()
{
    printf("m_x:%d, sizeof(MyTest):%d\n", MyTest::m_x, sizeof(m_x));
    return 0;
}

//输出:m_x:3242234
        sizeof(MyTest)=1

6.静态成员函数

        就像类中的静态成员变量一样,静态成员函数也不依赖于类的对象,不具体作用于某个对象。
        普通成员函数参数自带一个this指针,this指针指向类的对象本身,因为普通成员函数总是属于类对象,当函数被调用时,系统会把当前对象的起始地址赋给 this 指针。
        静态成员函数属于类本身,因此不具有this指针。它无法访问属于类对象的非静态成员变量和非静态成员函数,它只能访问其他静态成员变量和静态成员函数。
        可以通过对象来调用,但还是建议使 类名::静态成员函数 调用静态成员函数。
        静态成员函数和静态成员变量在类实例化之前就已经存在可以访问,而此时非静态成员还是不存在的,因此静态成员函数不能访问非静态成员变量。

        示例如下:

#include <iostream>
using namespace std;

class A
{
public:
	static int a; //类的静态成员变量
	static int get_a();//类的静态成员函数

	int b;
	int get_b();
};
int A::a = 100; //静态成员变量可以在类的外部直接定义
//int A::b = 1000; //普通成员变量在类的外部定义失败

int A::get_a()
{
	return a; //类的静态成员函数只能访问类的静态成员变量
	//return b + a; //静态成员函数无法调用普通成员变量
}
int A::get_b()
{
	return b + a;//普通成员函数可以调用静态成员变量
}

int  main(void)
{
	cout << "a: " << A::get_a() << endl; //不需要类的实例,也可以调用类的静态成员函数

	A m;
	m.b = 90;
	m.a = 100000;

	cout << m.get_a() << endl;
	cout << m.get_b() << endl;
	cout << m.a << endl;

	return 0;

}

7.总结

在使用关键字static的时候,我们需要注意一下几个原则:

  • static修饰的变量的存储位置都在静态区,且生命周期延长至整个程序运行结束。

  • static具有隔离作用,被static修饰的全局变量和全局函数的作用域由全局变为当前文件。

  • 静态变量虽然具有全局变量的生命周期,但只能作用于自己的作用域。

  • 普通静态成员需要在类的外面进行初始化。

  • 静态成员函数不能调用类的非静态成员,包括非静态成员和非静态成员函数。


网站公告

今日签到

点亮在社区的每一天
去签到