43.static的用法和作用?

发布时间 2023-07-03 21:46:23作者: CodeMagicianT

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++意义不同)
注意:只要文件不相互包含,两个不同的文件中是可以定义完全相同的两个全局静态变量的。

静态全局变量的特点如下:

  1. 只能在定义它的文件中访问,不能被其他文件访问。
  2. 生命周期与全局变量相同,即在程序启动时创建,在程序结束时销毁。
  3. 如果在定义时没有初始化,则默认值为0或者空字符。

使用静态全局变量的注意事项:

  1. 避免在多个文件中定义同名的静态全局变量,否则会导致命名冲突。
  2. 避免在头文件中定义静态全局变量,因为头文件可能被多个文件包含,会导致重复定义的问题。
  3. 静态全局变量的命名应该具有明确的前缀或者后缀,以避免与其他变量或者常量产生命名冲突。

下面是一个使用静态全局变量的示例:

#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]