43.static的用法和作用?
43.static的用法和作用?
在C++中,static
关键字有多种用法,可以用于声明静态成员变量、静态成员函数、静态局部变量和静态全局变量。下面是它们的作用和特点:
1.静态成员变量
●在类内声明,类外进行定义和初始化(const修饰的静态成员变量最好在类内初始化)
//const修饰的静态成员变量最好在类内初始化
class Maker
{
public:
const static int a = 20;
const static int b;
};
//类外也可以初始化
const int Maker::b = 30;
●静态成员变量属于类内,不属于对象,是所有对象共享,对每个对象只有一个实例,而不是默认的每个对象一个实例
●可以通过对象或类名访问(普通成员函数可以访问静态成员变量)
类的任何成员函数,包括静态成员函数,都可以直接访问类的静态数据成员。静态数据成员是与类本身相关联的,而不是与类的实例对象相关联的。因此,它们可以在类的任何成员函数中被访问和修改。
class Maker
{
public:
void func()
{
cout << "a=" << a << endl;
}
public:
static int a;
};
//类外也可以初始化
int Maker::a = 30;
void test()
{
Maker5 m;
m.func();
}
●静态成员也有权限,如果为私有,类外也不可以访问
class Maker3
{
private:
static void func()
{
cout << "a3=" << a3 << endl;
}
private:
static int a3;
};
int Maker3::a3 = 300;
void test()
{
//Maker3::func();err
}
●生命周期是整个程序,作用域在类内
2.静态成员函数
1.在类定义中,使用关键字static的成员函数称为静态成员函数。
2.静态成员函数定义可以使用类名前缀,也可以不使用类名前缀。
//不使用类名
class MyClass
{
public:
static int staticVar;
static void staticMethod()
{
std::cout << "staticVar = " << staticVar << std::endl;
}
};
int MyClass::staticVar = 0;
//不使用类名
class MyClass
{
public:
static int staticVar;
static void staticMethod();
};
int MyClass::staticVar = 0;
void MyClass::staticMethod()
{
std::cout << "staticVar = " << staticVar << std::endl;
}
3.静态成员函数的定义可以在类定义外部,也可以在类定义内部。在类外部定义的静态函数,可以在任何地方使用,而在类定义内部定义的静态成员函数,只能在类定义的范围内使用。
4.静态成员函数只能访问静态变量(包括类内和类外),不能访问普通成员变量(可以通过类的指针等作为参数间接访问)。静态成员函数不需要使用类名前缀,可以直接使用类的静态成员变量。
在类中定义静态成员函数时,它不需要使用类名前缀,可以直接使用类的成员变量。这是因为静态成员函数是该类的成员函数。
类的静态成员函数是类的全局函数,它们与类的实例对象无关,只与类本身相关。因此,它们无法直接访问普通数据成员,因为普通数据成员是与类的实例对象相关联的。但是,可以通过类的指针或引用来间接访问普通数据成员。
下面是一个示例代码,展示了静态成员函数对静态和非静态数据成员的访问:
#include <iostream>
using namespace std;
class MyClass
{
public:
static int staticVar; // 静态数据成员
int nonStaticVar; // 非静态数据成员
static void staticFunc()
{
cout << "Static function accessing static data member: " << staticVar << endl;
// 通过类的指针或引用来间接访问非静态数据成员
MyClass obj;
obj.nonStaticVar = 10;
cout << "Static function accessing non-static data member: " << obj.nonStaticVar << endl;
}
};
int MyClass::staticVar = 10; // 静态数据成员的初始化
int main()
{
MyClass::staticFunc(); // 调用静态成员函数
return 0;
}
3.静态局部变量
静态局部变量是定义在函数内部的局部变量,但是使用static关键字进行修饰。这意味着该变量的作用域仅限于该函数内部,但它的生命周期会持续到整个程序的运行期间。
静态局部变量的存储位置与全局变量类似,它们都存储在全局数据区中。与全局变量不同的是,静态局部变量的作用域仅限于函数内部,因此它们不会被其他函数所访问。
以下是一个示例代码,展示了静态局部变量的使用:
#include <iostream>
void myFunction()
{
static int myStaticVariable = 0; // 静态局部变量
myStaticVariable++;
std::cout << "myStaticVariable: " << myStaticVariable << std::endl;
}
int main()
{
myFunction(); // 输出:myStaticVariable: 1
myFunction(); // 输出:myStaticVariable: 2
myFunction(); // 输出:myStaticVariable: 3
return 0;
}
在这个例子中,我们定义了一个名为myFunction
的函数,其中包含一个静态局部变量myStaticVariable
。每次调用该函数时,该变量的值都会增加,因为它在程序运行期间只被初始化一次。如果没有使用static关键字修饰该变量,每次调用该函数时它都会被重新初始化,导致变量的值始终为0。
需要注意的是,静态局部变量的生命周期虽然比全局变量短,但它们的初始化时间与全局变量相同,都是在程序加载时进行的。因此,在程序运行期间,静态局部变量始终存在于内存中,直到程序退出。
静态局部变量和全局变量的生命周期是不同的。
生命周期:程序运行期一直存在;
作用域:局部作用域(只在局部作用域可见,超过其作用域便无法被引用)
内存分布:全局(静态存储区)。
定义方法:局部作用域中用static定义。
注意:只被初始化一次,多线程中需要加锁保护。
静态局部变量的作用域是从进入该函数开始到离开该函数结束,而全局变量的作用域是从程序开始到程序结束。因此,静态局部变量的生命周期比全局变量短。
在C++中,静态局部变量的生命周期从进入该函数开始到离开该函数不可见,而全局变量的生命周期从程序开始到程序结束。在C语言中,静态局部变量的生命周期与全局变量相同,都是从程序开始到程序结束 .
4.静态全局变量
静态全局变量是在函数外部定义的全局变量,但是使用了static
关键字进行修饰。静态全局变量的作用域仅限于定义它的文件,不能被其他文件访问。
生命周期:程序运行期一直存在,从程序开始到程序结束;
作用域:文件作用域(只在被定义的文件中可见:static的一个作用就是隐藏)
内存分布:全局(静态存储区)。
定义方法:static关键字,const关键字(注意C/C++意义不同)
注意:只要文件不相互包含,两个不同的文件中是可以定义完全相同的两个全局静态变量的。
静态全局变量的特点如下:
- 只能在定义它的文件中访问,不能被其他文件访问。
- 生命周期与全局变量相同,即在程序启动时创建,在程序结束时销毁。
- 如果在定义时没有初始化,则默认值为0或者空字符。
使用静态全局变量的注意事项:
- 避免在多个文件中定义同名的静态全局变量,否则会导致命名冲突。
- 避免在头文件中定义静态全局变量,因为头文件可能被多个文件包含,会导致重复定义的问题。
- 静态全局变量的命名应该具有明确的前缀或者后缀,以避免与其他变量或者常量产生命名冲突。
下面是一个使用静态全局变量的示例:
#include <stdio.h>
// 定义静态全局变量
static int myStaticGlobalVariable = 0;
int main()
{
// 访问静态全局变量
printf("myStaticGlobalVariable = %d\n", myStaticGlobalVariable);
myStaticGlobalVariable = 10;
printf("myStaticGlobalVariable = %d\n", myStaticGlobalVariable);
return 0;
}
在上面的示例中,myStaticGlobalVariable
是一个静态全局变量,只能在定义它的文件中访问。在main()
函数中,我们可以读取和修改它的值。由于静态全局变量的生命周期与程序相同,所以即使在程序执行过程中修改了它的值,下一次访问时仍然会读取修改后的值。
全局变量和静态变量自动初始化0
————————————————
参考资料:部分引用本文为CSDN博主「Nine_CC」的原创文章[https://blog.csdn.net/Nine_CC/article/details/105472698]