【学习笔记】C++ 中 static 关键字的作用

这篇具有很好参考价值的文章主要介绍了【学习笔记】C++ 中 static 关键字的作用。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

在 C/C++ 中,关键字 static 在不同的应用场景下,有不同的作用,这里总结一下,避免在使用时弄混。

我按照以下的逻辑来分类 static 的作用场景

  1. static 作用在变量上
    1. static 作用在全局变量上:限制全局变量在本文件上
    2. static 作用在局部变量上:即使离开变量作用域,也保存变量值,比如用作计数器
    3. static 作用在成员变量上 :对象间共享该变量
  2. static 作用在函数上
    1. static 作用在函数上:函数可见性限制在本文件中(即使函数被声明在头文件,引用该头文件的其他 cpp 文件也无法使用该函数)
    2. static 作用在成员函数
  3. static 作用在模板上

static 作用在变量上

static 作用在全局变量上

对于普通的全局变量来说,同一项目中的其他文件也可访问相同的全局变量,若为了限制全局变量在本文件中,则需要在这个全局变量上加一个 static,这样该变量就只能在本文件可见。

我们先来演示一下,如何在一个文件中使用另一个文件的全局变量。

假设有 a.cppb.cpp,我们在 b 中定义一个全局变量 staticValue,然后在 a 中打印出来。

// b.cpp
// 全局变量
int staticValue = 10;

void staticMain() {
	// ...
}
// a.cpp
#include <iostream>
using namespace std;

// 必须通过 extern 关键字在整个项目搜索 staticValue
extern int staticValue;

int main()
{
	cout << "在 a.cpp 中可见:" << staticValue << endl; // 在 a.cpp 中可见:10
}

显然我们成功在 a 文件中使用到了 b 文件内定义的全局变量。

现在,我希望将 staticValue 的全局可见性,限制在 b 文件内,不让其他文件也可以访问,于是我在 b 的 staticValue 前加上 static 关键字

// b.cpp
// 全局变量
static int staticValue = 10;

void staticMain() {
	// ...
}

将代码如上修改后,当我们再次运行时,程序会在链接阶段报错,报错信息如下,根据描述可见在 aobj 文件(汇编后生成的对象文件)里没有解析到 staticValue 这个变量,达到了我们限制全局变量在本文件内的目的
【学习笔记】C++ 中 static 关键字的作用,C++,static,关键字,C,C++

static 作用在局部变量上

static 作用在局部变量上,即使离开变量作用域,也保存变量值,比如用作计数器。效果如下面的代码所示

可以看到,num 的值是逐渐累加的过程

#include <stdio.h>

void count();

int main(void)
{
    int i=0;
    for (i = 0;i <= 5;i++)
    {
    	count();
    }
    return 0;
}
void count()
{
    /*声明一个静态局部变量*/
    static int num = 0;
    num++;
    printf("%d\n",num); // 1 2 3 4 5 6
}

static 作用在成员变量上

在这种情况下,static 标记的变量可以在多个对象之间共享该变量,在底层上,因为 static 标记的变量并非存在于对象的内存空间,而是存在于数据区中(这涉及到 C 语言的内存布局)。

具体的效果如下面代码所示,我们声明了 3 个学生对象,分别是 zhangsan,lisi 和 wangwu,并在定义他们的时候给他们传入了各自的初始分数,最终求得三个人的总分。

#include <iostream>
using namespace std;

class student {
private:
	static int sumScore;
	int myScore;
public:
	student(int m):myScore(m){
		sumScore += myScore;
	}

	int getSumScore() {
		return sumScore;
	}
};

int student::sumScore = 0; // 静态成员变量必须在类外被初始化

int main()
{
	student zhangsan(10);
	student lisi(20);
	student wangwu(30);

	cout << wangwu.getSumScore() << endl; // 60

	return 0;
}

关于 static 在修饰成员变量时的注意事项

  1. static 修饰的成员变量属于类,在对象间共享,因此某个对象修改了该变量,对其他对象也是可见的
  2. 静态成员变量的初始化必须要在类外,如上面的代码所示
  3. 静态成员变量的内存分配是发生在类外初始化的时候,而不是类或者对象创建的时候
  4. 静态成员变量可以通过类,也可以通过对象来访问,但必须遵守访问可见性(publicprivateprotected

static 作用在函数上

static 作用在函数上

它起到的效果和 static 作用在全局变量上类似,将函数的可见性限制在本文件内。

这里我们直接举被 static 修饰的函数的例子。

假设在 b.cpp 中我们定义了一个 bMain() 的函数,在 b.h 的头文件中进行声明,在 a.cpp 中引入这个头文件,并调用 bMain(),那么是可以正常调用的。

现在,我们在 b.cpp 中,在 bMain() 前加上一个 static 关键字,那么 a.cpp 就不能在调用了。

// b.cpp
#include <iostream>
using namespace std;

static void bMain() {
	cout << "bMain" << endl;
}
// b.hpp
void bMain();
// a.cpp
#include "b.hpp"

int main()
{
	bMain();

	return 0;
}

执行上述代码,我们可以看到和 “static 作用在全局变量上” 小节类似的报错问题
【学习笔记】C++ 中 static 关键字的作用,C++,static,关键字,C,C++

static 作用在成员函数上

静态成员函数具有和静态成员变量类似的性质和作用,一般可以用这种方式来确定类创建了多少个对象

  1. 静态成员函数在对象之间共享,或者说它独立于对象之外
  2. 可以通过对象来调用静态成员函数,也可以通过类名来调用静态成员函数
  3. 静态成员函数可以访问静态成员变量或其他静态成员函数,但不能使用当前对象指针
#include <iostream>
using namespace std;

class student {
private:
	static int sumObj;
public:
	student() {
		sumObj += 1;
	}
	static int getObjNum() {
		return sumObj;
	}
};

int student::sumObj = 0; // 静态成员变量必须在类外被初始化

int main()
{
	student zhangsan;
	student lisi;
	student wangwu;

	cout << "student 有几个对象? " << student::getObjNum() << endl; // 3

	return 0;
}

可以看到,最终我们输出了 3 个对象

static 作用在模板上

这里包括了函数模板和类模板,它们的逻辑都是一样的

  1. 描述:当是相同的模板实例时,static 修饰的变量在模板间共享;当是不同的模板实例时,static 修饰的变量独立存在于各个实例中。下面是一个例子
#include <iostream>
using namespace std;

template <typename T>
void fun()
{
  static int i = 1;
  cout << ++i << endl;
  return;
}

int main()
{
  // 前两个是相同的模板函数
  fun<int>();  // 2
  fun<int>();  // 3

  // 这是不同的模板函数
  fun<double>(); // 2

    return 0;
}

类模板也是一样的道理

#include <iostream> 
using namespace std;
  
template<class T> class Test
{
	public:
		static int count;
		Test(){};
		~Test(){};
		void add()
		{
			count++;
			cout << count << endl;
		}
};

template<class T>
int Test<T>::count = 0;

int main()
{
	Test<int> a;
	Test<int> b;
	Test<double> c;
	
	a.add(); // 1
	b.add(); // 2
	c.add(); // 1
}

【注】函数(类)模板是指的在文件中定义的,程序员自己写的模板部分。模板(类)函数是指在实例化时,编译器为我们生成的函数文章来源地址https://www.toymoban.com/news/detail-698235.html

参考

  1. 《Primer C++》
  2. Templates and Static variables in C++

到了这里,关于【学习笔记】C++ 中 static 关键字的作用的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言中volatile/register/const/static/extern/auto关键字的作用

    目录 一、volatile 二、register详解 三、const详解 四、static详解 五、extern详解 语法 作用 六、auto详解 突然想总结一下这些的作用,灵活使用这些对程序的可靠性和速率都有提高 volatile是防止编译器优化,如果是高频繁的变量编译器会自动将变量放到寄存器中,但是有的变

    2024年02月07日
    浏览(67)
  • 【C++】static 关键字的特性 与 问题

    声明为 static的类成员 称为 类的静态成员 用 static 修饰的成员变量 ,称之为 静态成员变量 ; 用 static 修饰的成员函数 ,称之为 静态成员函数 。 静态成员变量 一定要在 类外进行初始化 。 下面一段代码证明 上述定义: 输出结果: 从代码可以看出,静态成员变量需要在 类

    2024年02月14日
    浏览(50)
  • [开发语言][c++]:Static关键字和全局变量

    写在前面: 如果您只是想回顾或了解一下static和全局变量的异同点,那么下面的总结将满足您的需求。 如果您是一位初学者或对二者的使用模棱两可,建议您读完该篇文章,相信这一篇将解答完您对于static以及全局变量的所有疑惑。 如有问题或建议欢迎评论 or 私信

    2024年01月20日
    浏览(58)
  • 在C++和C中static关键字的用法,在C++和C中const关键字的用法

    1、在C++和C中static的用法 答:static表示存储类型,修饰数据类型。在C语言中,static修饰局部变量,内存分配在静态区,生命周期延长,作用域不变。static修饰全局变量,内存分配在静态区,作用域被局限于本文件,不能被extern引用。static修饰函数,不能被exter

    2024年02月10日
    浏览(41)
  • 重学C++系列之const与static关键字分析

            本篇幅讲解const与static,主要围绕在类的范围内叙述,包括作用和使用场景等。         1、const修饰的成员变量,成员变量初始化后不能再修改。         2、const修饰的成员函数,成员函数不可以修改成员变量,也不能间接修改。         3、static修饰的成员

    2024年02月15日
    浏览(46)
  • C++——初始化列表 | explicit关键字 | static成员

    🌸作者简介: 花想云 ,在读本科生一枚,致力于 C/C++、Linux 学习。 🌸 本文收录于 C++系列 ,本专栏主要内容为 C++ 初阶、C++ 进阶、STL 详解等,专为大学生打造全套 C++ 学习教程,持续更新! 🌸 相关专栏推荐: C语言初阶系列 、 C语言进阶系列 、 数据结构与算法 本章我们

    2023年04月11日
    浏览(50)
  • 【C++】const、static关键字和构造函数初始化

    💗个人主页💗 ⭐个人专栏——C++学习⭐ 💫点击关注🤩一起学习C语言💯💫 目录 1. const修饰成员函数 1.1 语法格式 1.2 权限放大缩小 1.3 思考 1.4 解答 2. 再谈构造函数 2.1 构造函数体赋值 2.2 初始化列表 2.3 explicit 3. static成员 3.1 静态变量 3.2 静态函数 3.3 静态成员变量

    2024年02月19日
    浏览(46)
  • 深入理解C++中的静态(Static)关键字及其应用场景

    在C++中,静态(Static)是一个常见且重要的概念,用于描述变量、函数和类成员。它具有独特的特性和作用域,可以在不同的应用场景中发挥重要作用。本文将详细讨论C++中的静态,包括静态变量、静态函数和静态类成员,并对其与全局变量之间的区别进行分析

    2024年02月09日
    浏览(49)
  • C++面试八股文:static和const的关键字有哪些用法?

    某日二师兄参加XXX科技公司的C++工程师开发岗位第7面: 面试官:C++中, static 和 const 的有哪些用法? 二师兄: satic 主要用在以下三个方面:1.用在全局作用域,修饰的变量或者函数为静态的,限制在本文件内使用。2.方法内修饰修饰静态局部变量,在第一次访问

    2024年02月08日
    浏览(48)
  • 第1关:学习-Java类和对象之static关键字之求圆环面积和周长

    本关任务:已知圆环的大圆半径 R 和 小圆半径 r 的长度分别为 32.0 和 10.0,求该圆环的面积和周长。 圆环面积公式为:S=π(R 2−r 2 ); 圆环周长公式为:C=2π(R+r)。 /** 任务:已知圆环的大圆半径 R 和 小圆半径 r 的长度分别为 32.0 和 10.0,求该圆环的面积和周长。 类名为:Ri

    2023年04月08日
    浏览(59)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包