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++中用于控制变量或函数的生命周期作用域,在代码优化、模块化设计等方面发挥着重要作用。

相关推荐
霁月风21 分钟前
设计模式——适配器模式
c++·适配器模式
萧鼎32 分钟前
Python并发编程库:Asyncio的异步编程实战
开发语言·数据库·python·异步
学地理的小胖砸33 分钟前
【一些关于Python的信息和帮助】
开发语言·python
疯一样的码农34 分钟前
Python 继承、多态、封装、抽象
开发语言·python
^velpro^35 分钟前
数据库连接池的创建
java·开发语言·数据库
秋の花43 分钟前
【JAVA基础】Java集合基础
java·开发语言·windows
jrrz082843 分钟前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
小松学前端1 小时前
第六章 7.0 LinkList
java·开发语言·网络
可峰科技1 小时前
斗破QT编程入门系列之二:认识Qt:编写一个HelloWorld程序(四星斗师)
开发语言·qt
咖啡里的茶i1 小时前
Vehicle友元Date多态Sedan和Truck
c++