static和const
static的作用
对变量而言:
在变量前加上关键词static,则会定义成一个静态变量。
该变量的内存在静态储存区,在整个程序的运行期间一直存在。
未经初始化的静态变量会自动初始化为0。
额外的:
普通的局部变量内存分配在栈上,会因为函数栈帧的释放而被释放掉,
而局部静态变量,在定义它的函数或者语句块结束时并没有销毁,而是仍在驻留在内存中且无法访问,直到再次调用它,并且值不变。
对于函数而言:
在函数返回类型前加static,函数就会定义成静态函数。
而该函数只能在定义它的源文件中使用,不能在其他源文件中被引用,因此也不会和其他源文件的同名函数起冲突。
对于类而言:
可以将一个类的成员或者函数修饰成静态成员或者静态函数。
它们属于类而不是某个对象。
static数据成员必须在类定义的外部定义。
所有的对象共享静态成员和静态函数。
静态成员通过<类名>::<静态成员名>来使用。
静态函数通过<类名>::<静态函数名>来使用。
静态成员函数的实现不能直接引用类中的非静态成员,也无法使用this指针。
也就是说,类的静态成员函数,只能调用该类的其它静态成员函数和静态数据成员
如果静态成员函数要引用非静态成员时,可通过对象来引用。
const的作用
const的目的就是定义一个“不会被修改的常量”,可以修饰变量、引用、指针,可以用于函数参数、成员函数修饰、成员变量。使用const可以减少代码出错的概率
例如用const修饰的成员函数表明函数调用不会对对象做出任何改变。
额外的:
针对于指针的const要分为顶层const和底层const,仅有指针和其他类型区别明显。
更常见的说法是指针常量和常量指针
指针常量则是顶层const,泛指意义上的const几乎都是顶层const,这里是指指针本身无法被修改。
指针常量指向的地址不会发生变化,地址本身是常量。
示例:
int const* p1 = &i;
而常量指针则是底层const,是说明指针指向的是一个常量。
当执行对象的拷贝操作时,拷入拷出的对象都必须具有相同的底层const资格,或者两个对象的数据类型必须能转换。
一般来说,非常量可以转换成常量,反之则不行。
示例:
const int *p2 = &i;
追加:
在一个复杂系统中很难分辨一个初始值到底是不是常量表达式。
当然可以定义个const变量并把它的初始值设为我们认为的某个常量表达式,但在实际使用时,尽管要求如此却常常发现初始值并非常量表达式的情况。
因此在C++11新标准规定中,允许将变量声明为constexpr类型以便由编译器来验证变量的值到底是否是一个常量表达式。声明为constexpr的变量一定是一个常量,而且必须用常量表达式初始化。
示例:
constexpr int sz = size();
说明:只有当size是一个constexpr函数时才是一条正确的声明语句。
通过上述示例可知尽管不能使用普通函数作为constexpr变量的初始值,但是允许定义一种特殊的constexpr函数。这种函数应该足够简单以使得编译时就可以计算其结果,这样就能用constexpr函数去初始化constexpr变量了。
一般来说,如果你认定变量是一个常量表达式,那就可把它声明成constexpr类型。
对比
const定义的常量在超出其作用域之后其空间会被释放;
而static定义的静态常量在函数执行后不会释放其存储空间。
static静态成员变量不能在类的内部初始化,在类的内部只是声明,定义必须在类定义体的外部;
const成员变量也不能在类定义处初始化,只能通过构造函数初始化列表进行,并且必须有构造函数。
static表示的是静态的,和类相关而不是和类的具体对象相关。即使没有具体对象,也能调用类的静态成员函数和成员变量。一般类的静态函数几乎就是一个全局函数,只不过它的作用域限于包含它的文件中;
const成员只在某个对象生存期内是常量,而对于整个类而言却是可变的。因为类可以创建多个对象,不同的对象其const数据成员的值可以不同,由于不能在类的声明中初始化const数据成员,要想建立在整个类中都恒定的常量,应该用类中的枚举常量来实现,或者static const。
const成员函数主要目的是防止成员函数修改对象的内容。
static成员函数主要目的是作为类作用域的全局函数。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具