广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++static详解,类中的static用法说明
  • 944
分享到

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

2024-04-02 19:04:59 944人浏览 薄情痞子
摘要

目录c++static详解,类中static用法static特点:用来控制存储方式和可见性类中的static关键字什么时候用static?为什么要引入static?c++中stati

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的函数指针; 

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

--结束END--

本文标题: C++static详解,类中的static用法说明

本文链接: https://www.lsjlt.com/news/164720.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

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

下载Word文档
猜你喜欢
  • C++static详解,类中的static用法说明
    目录C++static详解,类中static用法static特点:用来控制存储方式和可见性类中的static关键字什么时候用static?为什么要引入static?c++中stati...
    99+
    2022-11-13
  • 详解java中Static、final、Static final的各种用法
    对Static、final、Static final这几个关键词熟悉又陌生?想说却又不知怎么准确说出口?好的,本篇文章将简短概要出他们之间的各自的使用,希望各位要是被你的面试官问到了,也能从容的回答...static加载:static在类加...
    99+
    2015-12-04
    java入门 java Static final Static final
  • C语言中static和auto用法详解
    目录static的第一种用法:定义为静态变量static的第二种用法:有理说不清,直接代码见真知auto的用法:直接代码见真知总结static的第一种用法:定义为静态变量 何为静态变...
    99+
    2022-11-12
  • C/C++中的static关键字详解
    目录C/C++ 中的 static1. 静态局部变量2. 静态全局变量3. static 修饰函数C++的 static 成员静态成员变量 静态成员函数总结:static是...
    99+
    2022-11-13
  • C/C++ extern和static的使用详解
    目录前言externstaticc++ static members in class总结前言 在讲到extern和static的时候先了解一下定义和声明的基本概念 定义(defin...
    99+
    2022-11-13
  • c语言static关键字用法详解
    目录1.static修饰全局变量2.static修饰函数3.static修饰局部变量总结:1.static修饰全局变量 我们创建两个源文件,一个test.c,一个main.c 现在...
    99+
    2022-11-12
  • C语言中static的使用方法实例详解
    目录前言一、static修饰变量1.修饰局部变量2.修饰全局变量二、static修饰函数补充:static的好处是什么?总结前言 static关键字不仅可以用来修饰变量,还可以用来修...
    99+
    2022-11-13
    c语言static的用法 static作用 c语言 c语言static关键字的用法
  • c语言中static和extern的用法详细解析
    一,static和extern:大工程下我们会碰到很多源文档。文档a.c复制代码 代码如下:static int i; //只在a文档中用int j;  &nbs...
    99+
    2022-11-15
    c语言 extern static
  • 详解C语言中的Static关键字
    一、static关键字的基本含义 首先,static关键字的意思是静态的,用于修饰局部变量,全局变量和函数,修改其数据储存类型 1.局部变量:在任意一个函数内部定义的变量(不加sta...
    99+
    2022-11-13
  • 详解php用static方法的原因
    PHP中的静态方法是指在类中定义的可以直接通过类名调用的方法,而不需要实例化类对象。使用静态方法的主要原因有以下几点:1. 访问类成...
    99+
    2023-08-11
    php
  • 浅析C++中static的一些用法
    概述 Static,顾名思义是静态、静止的意思。在C语言中static是一个用来修饰变量与函数的关键字,被修饰对象的某些性质将发生根本性的改变,而这些变化从某种意义上又似乎契合了&l...
    99+
    2022-12-08
    static的用法 c++ static关键字
  • C语言中static的用法有哪些
    在C语言中,static关键字有以下几种用法:1. 在全局变量中使用static:当static关键字用于全局变量时,它的作用是限制...
    99+
    2023-08-08
    C语言 static
  • C++中static修饰符的详解及其作用介绍
    目录概述静态数据成员引用静态数据成员用类名访问数据成员静态成员函数综合案例概述 static (静态) 修饰符是用来控制变量的存储方式和可见性的. 静态局部变量存储在静态区域: s...
    99+
    2022-11-12
  • C语言中auto,register,static,const,volatile的区别详细解析
    1)auto这个关键字用于声明变量的生存期为自动,即将不在任何类、结构、枚举、联合和函数中定义的变量视为全局变量,而在函数中定义的变量视为局部变量。这个关键字不怎么多写,因为所有的变...
    99+
    2022-11-15
    register static const volatile
  • Java关键字详解之final static this super的用法
    目录1. final 关键字:2. static 关键字:3. this 关键字:4. super 关键字:final,static,this,super 关键字总结 正文开始@A...
    99+
    2022-11-12
  • C#中const,readonly和static关键字的用法介绍
    如果有一个值不太会变化,我们经常使用const和readonly,这2者有何不同呢?有时候,我们也会在readonly之前加上关键字static,这又意味着什么呢? const co...
    99+
    2022-11-13
  • Java类中this关键字与static关键字的用法解析
    目录前言1:修饰属性,表示调用类中的成员变量。2:this修饰方法3:this表示当前对象的引用前言 今天给大家总结介绍一下Java类中this关键字和static关键字的用法。 t...
    99+
    2022-11-13
  • 详解Java中static关键字的使用和原理
    目录概述定义和使用格式类变量静态方法调用格式静态原理图解静态代码块概述 关于 static 关键字的使用,它可以用来修饰的成员变量和成员方法,被修饰的成员是属于类的,而不是单单是属 ...
    99+
    2022-11-13
    Java static关键字 Java static
  • 带你了解Java中Static关键字的用法
    目录Java中Static关键字的一些用法详解1. Static 修饰类属性,因为静态成员变量可以通过类名+属性名调用,非静态成员变量不能通过类名+属性名调用;2. Static 修...
    99+
    2022-11-12
  • C++中new的用法及说明
    目录C++ new的用法知识点小结new的三种使用方法概念示例C++ new的用法 知识点小结 new其实就是告诉计算机开辟一段新的空间,但是和一般的声明不同的是,new开辟的空间在...
    99+
    2022-11-13
    C++中new new的用法 C++ new用法
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作