C/C++|static关键字


前言

本次学习C/C++中的static关键字,分别学习C语言和C++语言中的static特点。static是C、C++87中比较重要的一个关键字,它可以用来修饰变量、函数、类成员变量和类成员方法。


一、static变量

在变量声明前面加上static,变量就为静态变量。静态变量的特点:

  • 静态变量存储在全局数据区(包括static全局变量和static局部变量)
  • 静态变量的生命周期和程序一致,直到程序运行结束,才会释放静态变量占用的内存

1. static全局变量

如果static放在了全局变量声明的前面,那么该变量就为全局静态变量,其特点如下:

  • 作用域为整个程序
  • 在程序启动时初始化,如果没有显式初始化,则被初始化为0(自动变量初始化是随机的)
//a.cpp
#include <iostream>
static int a = 2233;	//static全局变量
int main()
{
    a = 2333;		
    std::cout << a << std::endl;
}
a = 2444;	//error:此声明没有存储类或类型说明符

//b.cpp
#include <iostream>
extern int a;
int main()
{
    a = 3334;
    std::cout << a << std::endl;
}

在编译b.cpp时会报错:

ld: Undefined symbols:
  _a, referenced from:
      _main in b-9ffdd0.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

2. static局部变量

如果在声明局部变量时加上static关键字,则表明该变量为static局部变量,其特点如下:

  • 作用域为当前函数或者语句块
  • 第一次调用该static局部变量时会进行初始化,以后调用不再初始化
#include <iostream>
static int a = 2233;

int function(){
    static int b = 1;
    std::cout << b << "\n";
    c = '1';//未定义标志符"c"
}
int main()
{
    a = 2333;
    b = a;//未定义标志符"b"
    static char c = '0';//
    std::cout << a << std::endl;
}

二、static函数

在函数的返回值类型前面加上static,即表明该函数为静态函数,其特点:

  • 只能在当前文件中被调用,其他文件无法调用该函数

好处在于其他文件可以有重名函数并且不会发生冲突。

#include <iostream>
static void function(){
    static int b = 1;
    b++;
    std::cout << b << "\n";
}
int main()
{
    function();//输出:2
    function();//输出:3
}

三、类静态成员变量/方法

类的静态成员变量和成员方法是所有类对象共享的,且类的静态成员变量和成员方法不需要实例化类对象也能访问,见代码:

  • int Player::m_playerCount = 0;
  • std::cout << "Number of Players: " << Player::GetPlayerCount() << std::endl
#include <iostream>

class Player{
public:
    Player(std::string name, int age){
        m_name = name;
        m_age = age;
        m_playerCount++;
    }
    static int GetPlayerCount() { return m_playerCount; }

    void PrintPlayerInfo(){
        std::cout << "name: " << this->m_name;
        std::cout << ", age: " << this->m_age << std::endl;
    }
private:
    std::string m_name;
    int m_age;
    static int m_playerCount;
};

int Player::m_playerCount = 0;

int main()
{
	std::cout << "Number of Players: " << Player::GetPlayerCount() << std::endl;//输出:Number of Players: 0
    Player p1("Bob", 12);
    p1.PrintPlayerInfo();//输出:name: Bob, age: 12
    std::cout << "Number of Players: " << p1.GetPlayerCount() << std::endl;//输出:Number of Players: 1 
    Player p2("Anna", 22);
    p2.PrintPlayerInfo();//输出:name: Anna, age: 22
    std::cout << "Number of Players: " << p2.GetPlayerCount() << std::endl;//输出:Number of Players: 2
}

1.类静态成员变量

见上述代码中,m_playerCount为静态成员变量,用来记录玩家数量,在实例化类对象前必须要对该静态成员变量初始化,否则会报错,报错信息如下:

ld: Undefined symbols:
  Player::m_playerCount, referenced from:
      Player::GetPlayerCount() in a-85fe5c.o
      Player::Player(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char>>, int) in a-85fe5c.o
clang: error: linker command failed with exit code 1 (use -v to see invocation)

每实例化一个Player对象时,m_playerCount都会增加1,同样,每销毁一个Player对象时,m_playerCount都应该减1(代码中没实现,后续类的介绍中会讲)。

2.类静态成员方法

见上述代码中的GetPlayerCount()函数,它返回此时的玩家数量。

总结

本次学习了在C/C++中的static关键字,其中在C程序中只会存在static全局(局部)变量和static函数,类静态成员变量和成员方法只有C++中才有,这是C++的面向对象思想的特点。

  • 9
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值