我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++static详解,类中的static用法说明

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++static详解,类中的static用法说明

C++static详解,类中static用法

static特点:用来控制存储方式和可见性

① 存储空间:静态存储区(控制变量的存储方式)

静态变量存储在静态存储区(存储在静态存储区的变量,如果不显式地对其进行初始化,系统会将其初始化为0),在程序执行期间,对应的存储空间不会释放,一直到程序结束才会释放。

static控制变量的存储方式体现在局部变量上。局部变量存储在动态存储区,在局部变量定义前加上static,该局部变量就变成了局部静态变量,局部静态变量存储在静态存储区,即使函数调用结束,它占用的存储空间也不会释放,但其他函数不能引用该局部静态变量。当下一次调用该函数时,不会再次对该局部静态变量进行初始化,它的值是上一次函数调用结束时的值。

对全局变量而言,存储方式没有什么改变,因为全局变量和全局静态变量都存储在静态存储区。

② 作用域:(控制变量、函数的可见性)

static控制变量的可见性体现在全局静态变量和静态函数上。

全局变量默认具有外部链接性,作用域是整个工程。使用static关键字可以限制全局变量的作用域,全局静态变量的作用域仅限本文件,它对在其他文件不可见,也就是说不能在其他文件中引用该全局静态变量,但其他文件中可以定义和它名字相同的变量,不会发生冲突。

在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数的不同在于,它只能在声明它的文件当中可见,不能被其它文件使用,其它文件中可以定义相同名字的函数,不会发生冲突。

局部静态变量的作用域与局部变量的作用域相同,其作用域都是从定义开始到函数或程序块结束为止。

类中的static关键字

在类中声明static变量或者函数时,初始化时使用作用域运算符(::)来标明它所属类,静态成员是类的成员(所有对象中共享的成员),而不是某一个对象的成员。

① 静态数据成员

在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。

静态数据成员和普通数据成员一样遵从public,protected,private访问规则。

对于非静态数据成员,每个对象都有自己的拷贝。而静态数据成员被当作是类的成员。无论这个类的对象被定义了多少个,静态数据成员在程序中也只有一份拷贝,由该类的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的多个对象来说,静态数据成员只会被分配一次内存,供所有对象共用。所以,静态数据成员的值对每个对象都是一样的,它的值可以更新。

因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于特定的对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们就可以操作它。

同全局变量相比,使用静态数据成员有两个优势:

静态数据成员没有进入程序的全局名字空间,因此不存在与程序中其它全局名字冲突的可能性;

可以实现信息隐藏。静态数据成员可以是private成员,而全局变量不能;

② 静态成员函数

与静态数据成员一样,我们也可以创建一个静态成员函数,它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个this指针,this指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this是缺省的,如函数fun()实际上是this->fun()。但是与普通函数相比,静态成员函数由于不与任何的对象相联系,因此它不具有this指针。

非静态成员函数可以任意地访问静态成员函数和静态数据成员;

静态成员函数不能访问非静态成员函数和非静态数据成员;静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;

什么时候用static?

需要一个数据对象为整个类而非某个对象服务,同时又力求不破坏类的封装性,即要求此成员隐藏在类的内部,对外不可见。

为什么要引入static?

函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题:如果想将函数中此变量的值保存至下一次调用时,如何实现?最容易想到的方法是定义一个全局的变量,但定义为一个全局变量有许多缺点,最明显的缺点是破坏了此变量的访问范围(使得在此函数中定义的变量,不仅仅受此函数控制)。

c++中static总结

经过static修饰的变量,存储在内存的全局静态区。且被static修饰的变量只能在本模块的所有函数引用。

内存中的存储区域如下:

  • 堆区:是由程序员手动申请(new)与释放(delete)的内存区域。从低地址向高地址申请;内存空间大、存储地址不连续,一般是链式的;速度较慢。
  • 栈区:由编译器自动分配和释放,主要存储 函数的参数值、函数内部的变量的值、函数调用的空间。从高地址向低地址申请;容量有限;速度较快;存储地址连续,会溢出。
  • 代码区:又叫文本段(.text),存放着程序的机器代码,可执行指令就是存储在这里的,这里的代码是只读的。
  • 全局区(静态区):全局变量和静态变量是存储在这里的。初始化的全局变量和静态变量在一块区域(.data),未初始化的全局变量和未初始化的静态变量在相邻的另一块区域(.bbs)。系统结束后由系统释放。
  • 常量区:常量字符串放在这里,程序结束后,由系统进行释放。

1. 概念

static的用法主要体现在两个方面:面向过程中的static和面向对象中的static。

面向过程的static主要包括静态全局变量、静态局部变量和静态函数。

面向对象的static主要包括静态成员变量、静态成员函数。

2. 面向过程的static

2.1 静态全局变量

全局变量前添加static关键字,则该变量称为静态全局变量。

#include <iostream>
#include <stdio.h>
 
static int a = 10;
 
void Func()
{
    a++;
}
 
int main()
{
    printf("a = %d\n", a);//输出:10
    Func();//输出:10
    printf("a = %d\n", a);//输出:11
 
    system("pause");
    return 0;
}

特点:

1)在全局数据中的变量如果没有显示的初始化会自动被程序初始化为0(这个特性非静态全局变量也有),而在函数体内声明的变量如果不显示初始化则会使一个随机值;

2)静态全局变量在声明它的整个文件中都是可见的,而在文件之外是不可见的;

3)静态全局变量在全局数据区分配内存;

4)其他文件中可以定义同名int型变量a,不会冲突;

如果将static去掉,具有以下特点:

1)全局变量默认是有外部连接性的,其作用域是整个工程,在一个文件内定义的全局变量可以通过包含其所在头文件或显示调用 extern关键字修饰全局变量的变量名声明来引用;

2)静态全局变量是显示调用static修饰的全局变量,其作用域只在声明此变量的文件中,其他文件即使使用extern关键字修饰其声明也不可使用;

2.2 静态局部变量

局部变量前添加static关键字,则该变量称为静态局部变量。

#include <iostream>
#include <stdio.h>
 
void Func()
{
    static int a = 5;
    printf("a = %d\n", a);
    a++;
}
 
int main()
{
    for (int i = 0; i < 5; i++)
    {
        Func();  //打印结果:5 6 7 8 9
    }
 
    system("pause");
    return 0;
}

通常,在一个函数作用域内定义一个变量,每次运行到该函数时,系统会给局部变量分配内存。当函数结束时,该变量的内存会被系统回收至栈内存当中。

特点:

1)内存存放在程序的全局数据区中;

2)静态局部变量在程序执行到该对象声明时,会被首次初始化。其后运行到该对象的声明时,不会再次初始化,这也是为什么上面程序测试函数每次输出的值都是递增的原因(只会被初始化一次);

3)如果静态局部变量没有被显式初始化,则其值会自动被系统初始化为0;

4)局部静态变量不能被其作用域之外的其他模块调用,其调用范围仅限于声明该变量的函数作用域当中;

2.3 静态函数

函数返回类型前添加static关键字,则该变量称为静态函数。

#include <iostream>
#include <stdio.h>
 
static void Func()
{
    printf("This is a static function\n");
}
 
int main()
{
    Func(); 
    
    system("pause");
    return 0;
}

特点:

1)作用域只在声明它的文件当中,不能被其他文件引用,其他文件可以定义同名的全局函数;

2)其他文件想要调用本文件的静态函数,需要显示的调用extern关键字修饰其声明;

3. 面向对象中的static 

3.1 静态成员变量

#include <iostream>
#include <stdio.h>
using namespace std;
 
class Test
{
public:
    Test(int a, int b, int c) : 
        m_a(a),
        m_b(b),
        m_c(c)
    {
        m = a + b + c;
    }
 
    void Show()
    {
        cout << "m = " << m << endl;
    }
 
private:
    int m_a, m_b, m_c;
    static int m;
};
 
int Test::m = 0; //初始化静态数据成员
 
int main()
{
    Test ClassA(1, 1, 1);
    ClassA.Show();  //输出: 3
    Test ClassB(3, 3, 3);
    ClassB.Show(); //输出: 9
    ClassA.Show(); //输出: 9
 
    system("pause");
    return 0;
}

特点:

1)静态数据成员的服务对象并非是单个类实例化的对象,而是所有类实例化的对象(这点可以用于设计模式中的单例模式实现);

2)静态数据成员必须显式的初始化分配内存,在其包含类没有任何实例化之前已经有内存分配;

3)静态数据成员与其他成员一样,遵从public,protected,private的访问规则;

4)静态数据成员内存存储在全局数据区,只随着进程的消亡而消亡;

优势:

1)静态数据成员不进入程序全局命名空间,不会与其他全局名称的同名同类型变量冲突;

2)静态数据成员可以实现C++的封装特性,由于其遵守类的访问权限规则,所以相比全局变量更加灵活;

3.2 静态成员函数

类的成员函数返回类型之前添加static,此成员函数为静态成员函数。

#include <iostream>
#include <stdio.h>
using namespace std;
 
class Test
{
public:
    Test(int a, int b, int c) : 
        m_a(a),
        m_b(b),
        m_c(c)
    {
        m = a + b + c;
    }
 
    static void Show()
    {
        cout << "m = " << m << endl;
    }
 
private:
    int m_a, m_b, m_c;
    static int m;
};
 
int Test::m = 0; //初始化静态数据成员
 
int main()
{
    Test ClassA(1, 1, 1);
    ClassA.Show();
    Test ClassB(3, 3, 3);
    ClassB.Show();
    ClassA.Show();
 
    Test::Show(); //输出: 9
 
    system("pause"); 
    return 0;
}

特点:

1)静态成员函数比普通成员函数多了一种调用方式;

2)在没有实例化的类对象的条件下可以调用类的静态成员函数;

3)静态成员函数中没有隐含的this指针,所以静态成员函数不可以操作类中的非静态成员(由于第二条可知,类的非静态成员是在类实例化后存在的,而类的成员函数可以在类没有实例化的时候调用,故不能操作类的非静态成员);

4. 小结

1)静态数据成员都是静态存储的,所以必须在main函数之前显示的对其进行初始化;

2)不能再头文件中声明静态全局变量,原因是可能是产生了多个同名的静态数据;

3)不能将静态成员函数定义为虚函数;

4)静态成员函数没有this指针;

5)static缩短了子类对父类静态成员访问的时间,相对来说节省了内存空间;

6)如果不想在子类中操作父类的静态成员,则可以在子类中定义一个同名的static成员。这样既可覆盖父类中的静态成员,并且根据C++的多态性变量命名规则,这样做是安全的;

7)静态成员声明在类中,操作在其外部,所以对其取地址操作就跟取普通成员的操作略有不同。静态变量地址是指向其数据类型的指针,函数地址则是一个类型为nonmember的函数指针; 

以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程网。

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++static详解,类中的static用法说明

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

详解java中Static、final、Static final的各种用法

对Static、final、Static final这几个关键词熟悉又陌生?想说却又不知怎么准确说出口?好的,本篇文章将简短概要出他们之间的各自的使用,希望各位要是被你的面试官问到了,也能从容的回答...static加载:static在类加载时初始化(加载)完
详解java中Static、final、Static final的各种用法
2015-12-04

c++中static的用法

摘要:c++ 中的 static 关键字用于声明具有静态存储持续期的变量、函数和类成员。静态变量在整个程序生命周期内都存在,静态函数仅限于访问当前文件中的数据,静态数据成员在所有对象之间共享。C++ 中 static 的用法static
c++中static的用法
2024-05-06

static在c++中的用法

static是c++中的一个关键字,用于声明变量、函数和类成员,拥有以下特性:变量:只有一份副本,在启动时初始化,在结束时销毁,即使未被使用也占内存。函数:只能访问本函数中的变量,不能重载。类成员:属于类而不是实例,可以使用类名访问,只能访
static在c++中的用法
2024-05-14

C语言中static的使用方法实例详解

static一般用于修饰局部变量,全局变量,函数,下面这篇文章主要给大家介绍了关于C语言中static用法的相关资料,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
2022-11-13

c++中static的作用和用法

c++ 中的 static 关键字用于声明静态变量、函数或类成员,使其在程序生命周期内存在或与类的每个实例关联。具体用法如下:静态变量:在函数外声明,仅创建一份副本,在程序启动时初始化且值保留至程序结束。静态函数:在类或结构体外声明,无法访
c++中static的作用和用法
2024-05-14

c语言中static和extern的用法详细解析

以下是对c语言中static和extern的用法进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
2022-11-15

c++中static的用法和作用

c++ 中的 static 关键字用于修改变量、函数和类成员,指示编译器保留其作用域和存储持续时间。其用法包括:声明 static 变量以保留函数调用或对象销毁后的值。声明 static 成员变量以在类的不同实例之间共享数据。使用 stat
c++中static的用法和作用
2024-05-08

c语言中的static的用法

在 c 语言中,static 关键字用于修饰变量、函数或类成员,使其具有静态作用域,具有以下特性:内部链接:只能在声明它的文件中访问或调用。保留值:变量和局部函数变量在程序结束之前保留其值。类作用域:类成员属于整个类,所有实例共享同一份数据
c语言中的static的用法
2024-05-09

浅析C++中static的一些用法

static是静止的,静态的意思,那它有什么用呢,今天通过实例代码讲解下C++中static的一些用法,感兴趣的朋友跟随小编一起看看吧
2022-12-08

详解php用static方法的原因

PHP中的静态方法是指在类中定义的可以直接通过类名调用的方法,而不需要实例化类对象。使用静态方法的主要原因有以下几点:1. 访问类成员:静态方法可以直接访问类中的静态成员变量和静态方法,而不需要创建类的实例。这样可以方便地在没有创建对象的情
2023-08-11

C语言中static的用法有哪些

在C语言中,static关键字有以下几种用法:1. 在全局变量中使用static:当static关键字用于全局变量时,它的作用是限制该变量的作用范围只在当前源文件中。即该变量在其他源文件中是不可见的。```cstatic int count
2023-08-08

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录