c++ static(详解)

C++ 中,static 关键字用于定义具有静态存储持续时间 的变量或方法。它在不同上下文中有不同的含义,通常与变量的存储方式和作用域相关。static的主要作用是控制变量或函数的可见性和生命周期。

可以通过一个生活中的场景来形象化static的作用:

场景:

假设你是一位图书馆管理员,负责管理图书馆中每个人的借书记录。每次有新成员登记时,你都为他们创建一个新的借书账户,并记录他们借的书。但图书馆有一个总借书数的统计,也就是说,不管有多少个会员借书,所有人的借书数量都会加在一起,形成一个全馆的总借书数。

静态变量的作用:

  • 借书账户的个人记录:每个会员都有自己借书的记录(类似于类的普通成员变量),每个人只能看到自己借了几本书。
  • 图书馆的总借书数 :图书馆有一个总借书数的统计,这个数字对所有会员来说是共享的(类似于**static**成员变量),每个会员借了一本书后,这个总数都会增加。

对应到C++代码:

cpp 复制代码
#include <iostream>

using namespace std;

class LibraryMember{
public:
    int personalBorrowedBooks = 0; //个人借书记录

    static int totalBorrowedBooks; //总借书数(所有人共享)

    void borrowBook(){
        personalBorrowedBooks++; //总借书数增加
        totalBorrowedBooks++; //总借书数增加
    }
    void showBorrowInfo(){
        cout <<"You have borrowed " << personalBorrowedBooks << " books." << endl;
        cout <<"The liberary has loand out " << totalBorrowedBooks << " book in total." << endl;
    }

};

//初始化静态成员变量
int LibraryMember::totalBorrowedBooks = 0;

int main(){

    LibraryMember member1;
    LibraryMember member2;

    member1.borrowBook();  // member1借了1本书
    member2.borrowBook();  // member2借了1本书
    member1.borrowBook();  // member1又借了1本书

    cout << "memeber1 Info " << endl;
    member1.showBorrowInfo() ;  // 显示member1的信息
    cout << "memeber2 Info " << endl;
    member2.showBorrowInfo();  // 显示member2的信息

    return 0;
}

输出结果:

cpp 复制代码
memeber1 Info 
You have borrowed 2 books.
The liberary has loand out 3 book in total.
memeber2 Info 
You have borrowed 1 books.
The liberary has loand out 3 book in total.

分析:

  1. 个人借书记录(非静态成员变量) :每个**LibraryMember** 对象有自己独立的借书记录。member1 借了2本书,而**member2**借了1本书,他们各自的记录是独立的。
  2. 总借书数(静态成员变量):所有成员共享一个总借书数,不管是哪个成员借了书,这个总借书数都会增加。

静态的现实意义:

**static**就像图书馆的总借书统计,它不会因为某个会员的加入或离开而被重新设置或注销,始终保持一个全局的、共享的状态。这类似于生活中我们对一些全局、共享数据的统计与追踪,所有人都可以贡献,但数据是统一维护的。

  1. 静态成员变量

静态成员变量(类的静态变量)属于整个类,而不是某个具体的对象。它们在所有对象中共享,也就是说,不管创建了多少个类对象,静态成员变量在内存中只有一份,且对所有对象都是共用的。

  • 作用:用于存储类的全局状态,所有对象共享该状态。
cpp 复制代码
class MyClass {
public:
    static int staticVar;
    MyClass() { staticVar++; }  // 每次创建对象时都会递增
};

int MyClass::staticVar = 0;  // 静态变量需要在类外初始化

int main() {
    MyClass obj1;
    MyClass obj2;
    cout << MyClass::staticVar;  // 输出 2
}

2. 静态成员函数

静态成员函数和静态成员变量类似,它们属于整个类,而不是某个对象。静态成员函数只能访问静态成员变量,不能访问非静态成员变量,因为非静态成员变量依赖于具体的对象实例。

  • 作用:用于不依赖对象的功能实现,比如操作静态成员变量。
cpp 复制代码
class MyClass {
public:
    static int staticVar;
    static void printStaticVar() {
        cout << staticVar << endl;  // 可以访问静态变量
    }
};

int MyClass::staticVar = 0;

int main() {
    MyClass::printStaticVar();  // 直接通过类名调用静态函数
}

3. 静态局部变量

在函数内部,static 局部变量的生命周期贯穿整个程序的执行,而不仅仅是在函数调用期间。它在函数第一次被调用时初始化,并在程序的整个生命周期内保持其值。

  • 作用:用于需要在函数多次调用时保持其状态的场景。
cpp 复制代码
void countCalls() {
    static int count = 0;  // 只初始化一次
    count++;
    cout << "This function has been called " << count << " times" << endl;
}

int main() {
    countCalls();  // 输出 1
    countCalls();  // 输出 2
    countCalls();  // 输出 3
}

4. 静态全局变量

static 修饰的全局变量(在函数或类外定义)只能在定义它的文件中访问,无法被其他文件访问。这是一种用于控制链接的方式,通常用于实现模块间的数据隔离,防止名称冲突。

  • 作用:用于在一个源文件中定义只对该文件可见的变量。
cpp 复制代码
static int fileVar = 0;  // 只能在当前文件中使用

5. 静态函数(文件作用域)

类似于静态全局变量,static 修饰的函数只能在定义它的文件中使用。这在大型项目中非常有用,因为它可以防止不同文件中的函数名冲突。

  • 作用:用于限制函数的可见性,使其仅在定义的文件中可用。
cpp 复制代码
static void helperFunction() {
    // 只能在当前文件中调用
}

6. 使用场景总结

  • 共享类成员:静态成员变量和静态成员函数在类的不同实例之间共享数据。
  • 维护函数状态:静态局部变量用于在函数调用之间保持状态。
  • 文件级作用域:静态全局变量和静态函数用于实现文件内的变量和函数封装,避免命名冲突。
  • 效率提升:静态成员函数可以在不创建对象的情况下直接调用,减少对象的开销。

static 在C++中用于控制变量或函数的生命周期作用域,在代码优化、模块化设计等方面发挥着重要作用。

相关推荐
轻口味1 小时前
命名空间与模块化概述
开发语言·前端·javascript
晓纪同学2 小时前
QT-简单视觉框架代码
开发语言·qt
威桑2 小时前
Qt SizePolicy详解:minimum 与 minimumExpanding 的区别
开发语言·qt·扩张策略
飞飞-躺着更舒服2 小时前
【QT】实现电子飞行显示器(简易版)
开发语言·qt
明月看潮生2 小时前
青少年编程与数学 02-004 Go语言Web编程 16课题、并发编程
开发语言·青少年编程·并发编程·编程与数学·goweb
明月看潮生2 小时前
青少年编程与数学 02-004 Go语言Web编程 17课题、静态文件
开发语言·青少年编程·编程与数学·goweb
Java Fans2 小时前
C# 中串口读取问题及解决方案
开发语言·c#
盛派网络小助手2 小时前
微信 SDK 更新 Sample,NCF 文档和模板更新,更多更新日志,欢迎解锁
开发语言·人工智能·后端·架构·c#
Chinese Red Guest3 小时前
python
开发语言·python·pygame
一棵星3 小时前
Java模拟Mqtt客户端连接Mqtt Broker
java·开发语言