C++之static关键字的作用

本文深入探讨了C++中static关键字的使用,包括全局和局部静态变量的作用域及初始化特性,static函数的模块限制,以及静态数据成员和静态成员函数在类中的应用。通过实例,解释了静态成员如何为所有对象共享同一份拷贝。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、 static声明全局静态变量和局部静态变量

1、static声明全局静态变量
该全局变量作用域被改变,只能供本模块使用。不能被其他模块再声明extern变量,多个模块可以同时定义同名static全局变量。

2、static声明局部静态变量
静态局部变量可以理解为是一个供函数局部存取的全局变量
a、生存期为整个源程序,但是其作用域仍与自动变量相同,只能在定义该局部静态变量的函数中存取。
b、函数多次进入,变量的值只能在第一次进入初始化,也是唯一的一次初始化。

注意:static声明的变量(整形或浮点型)的默认初始化都为0(储存在全局区)。

二、static声明的普通函数

普通函数不能嵌套定义,所以没有局部函数和全局函数一说。

全局变量默认是非extern的,而普通的函数,默认是extern的,也就是说它用不用extern声明都可以被其他模块调用(前提其他模块中也有该函数的声明)。用static修饰的函数,限定在本模块中,不能被本身以外的模块调用。所以不会导致不同模块中声明、定义的同名函数发生冲突。

三、C++中的静态数据成员和静态函数成员

不管这个类创建了多少个对象,其静态成员在内存中只保留一份拷贝,这个拷贝为该类的所有对象所共享。

1、静态成员数据
a、静态数据成员的访问属性同普通数据成员一样,可以为public、private和protected。
b、静态数据成员脱离具体对象而独立存在,其存储空间是独立分配的,不是任何对象存储空间的一部分,但逻辑上所有的对象都共享这一存储单元,所以对静态数据成员的任何操作都将影响共享这一存储单元的所有对象。
c、静态数据成员是一种特殊的数据成员,它为类属性,而不是某个对象单独的属性,它在程序开始产生,在程序结束时消失。静态数据成员具有静态生存期。
d、由于在类的定义中仅仅是对静态数据成员进行了引用性声明,因此必须在文件作用域的某个地方对静态数据成员进行定义并初始化,即应在类体外对静态数据成员进行初始化(静态数据成员的初始化与它的访问控制权限无关),对象的初始化应不需要再对静态数据初始化。
e、静态数据成员初始化时前面不加static关键字,以免与一般静态变量或对象混淆。
f、由于静态数据成员是类的成员,因此在初始化时必须使用类作用域运算符::限定它所属的类。

#include<iostream>
using namespace std;
class Student {
public:
	char *Name;
	int No;
	static int sc;
};
//在类外对静态成员初始化如下:
int Student::sc;//默认初始化的值为0,一般初始化为:int Student::sc=数值
int main()
{
	Student a = { "dahuzideaiwa",2 };//Student a = { "dahuzideaiwa",2,90 };错误
	cout << a.sc << endl;
	a.sc = 90;cout << a.sc << endl;
	return 0;
}
/*运行结果:
0
90
*/

2、静态成员函数
a、静态成员函数的访问权限同普通成员函数一样。
b、静态成员函数也可以省略参数、使用默认形参值、以及进行重载。
c、不能将静态成员函数定义为虚函数。
d、static并没有增加程序的时空间开销,相反在子类对父类静态成员的访问时缩短了时间开销,节省了子类的内存空间。
e、静态成员函数与普通成员函数在使用还有如下区别:
由于静态成员函数在类中只有一个拷贝(副本),因此它访问对象的成员时要受到一些限制:静态成员函数可以直接访问类中说明的静态成员,但不能直接访问类中的非静态成员;若要访问非静态成员,必须通过参数传递的方式得到相应的对象,再通过对象来访问。
由于静态成员是独立于类对象而存在的,因此静态成员没有this指针。

f、不需要生成对象就可以访问静态成员函数。

如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.youkuaiyun.com/qq_43148810

<think>我们正在讨论C++中的static关键字。根据引用内容,staticC++中用于修饰变量、函数和成员,主要作用是控制存储方式和作用范围。下面我将详细解释static的几种用法。 1. **静态局部变量**:在函数内部使用static修饰的局部变量。这种变量在程序运行期间只初始化一次,且生命周期持续到程序结束。每次函数调用,该变量保持上次调用结束的值。例如: ```cpp void func() { static int count = 0; // 只初始化一次 count++; cout << count << endl; } ``` 调用`func()`三次会输出1, 2, 3。因为`count`在函数调用之间保持其值。 2. **静态全局变量/函数**:在全局作用域(函数外部)使用static修饰的变量或函数,其作用域仅限于定义它的文件(编译单元)。这样避免了命名冲突,也实现了信息隐藏。例如: ```cpp // file1.cpp static int globalVar = 42; // 只在file1.cpp中可见 // file2.cpp extern int globalVar; // 错误!无法访问file1.cpp中的globalVar ``` 3. **静态成员变量**:在内部用static修饰的成员变量。它属于整个,而不是某个对象,因此被所有对象共享。必须在外定义和初始化(除非是C++17引入的inline static)。例如: ```cpp class MyClass { public: static int count; // 声明 }; int MyClass::count = 0; // 定义和初始化 // 使用:MyClass::count 或 obj.count(不推荐通过对象访问) ``` 4. **静态成员函数**:用static修饰的成员函数。它属于而不是对象,因此不能访问非静态成员(因为没有this指针)。可以通过名直接调用。例如: ```cpp class MyClass { public: static void printCount() { cout << count << endl; // 正确,count是静态成员变量 // cout << data; // 错误!不能访问非静态成员 } private: int data; static int count; }; ``` 总结static关键字作用: - 延长局部变量的生命周期(使其具有静态存储期) - 限制全局变量/函数的作用域(文件作用域) - 实现的成员变量和函数由所有对象共享 这些特性使得static在模块化设计、数据共享和状态保持等场景中非常有用。 §§相关问题§§ 1. 静态成员变量在中如何初始化? 2. 为什么静态成员函数不能访问非静态成员变量? 3. 静态局部变量和全局静态变量有什么区别? 4. 在多线程环境下使用static变量需要注意什么?</think>### C++中`static`关键字作用详解 `static`关键字C++中有多种用法,主要控制变量和函数的**存储方式**和**作用范围**。以下是核心作用: --- #### 1. **静态局部变量** 在函数内部声明,生命周期延长至程序结束,且**只初始化一次**: ```cpp void counter() { static int count = 0; // 只初始化一次 count++; std::cout << count << "\n"; } // 调用 counter() 三次输出:1, 2, 3 ``` - **特点**:函数退出后值仍保留,下次调用沿用上次的值[^3]。 --- #### 2. **静态全局变量/函数** 在全局作用域使用`static`,限制作用域为**当前文件**: ```cpp // file1.cpp static int globalVar = 100; // 仅file1.cpp可见 static void helper() { ... } // 仅file1.cpp可调用 ``` - **作用**:避免多文件编译的命名冲突,实现模块化封装[^1][^3]。 --- #### 3. **静态成员变量** 在中声明,被**所有对象共享**: ```cpp class MyClass { public: static int sharedCount; // 声明 }; int MyClass::sharedCount = 0; // 外定义初始化 ``` - **特点**: - 不属于任何对象,通过`名::变量名`访问(如`MyClass::sharedCount`)。 - 替代全局变量,避免命名污染[^2]。 --- #### 4. **静态成员函数** 属于而非对象,**无`this`指针**: ```cpp class MyClass { public: static void printCount() { std::cout << sharedCount; // 只能访问静态成员 } }; // 调用:MyClass::printCount(); ``` - **限制**: - 不能访问非静态成员(因无对象实例)[^2][^3]。 --- ### 总结对比 | 型 | 作用域 | 生命周期 | 关键特性 | |---------------------|----------------------------|----------------|------------------------------| | 静态局部变量 | 函数内部 | 程序结束 | 只初始化一次,保留状态 | | 静态全局变量/函数 | 当前文件 | 程序结束 | 避免跨文件命名冲突 | | 静态成员变量 | 作用域 | 程序结束 | 所有对象共享,初始化 | | 静态成员函数 | 作用域 | - | 无`this`指针,仅访问静态成员 | ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大胡子的艾娃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值