一文读懂c++之static关键字

一、静态变量

与C语言一样,可以使用static说明自动变量。根据定义的位置不同,分为静态全局变量和静态局部变量。

  • 全局变量是指在所有花括号之外声明的变量,其作用域范围是全局可见的,即在整个项目文件内都有效。使用static修饰的全局变量是静态全局变量,其作用域有所限制,仅在定义该变量的源文件内有效,项目中的其他源文件中不能使用它。
  • 块内定义的变量是局部变量,从定义之处开始到本块结束处为止是局部变量的作用域。使用static修饰的局部变量是静态局部变量,即定义在块中的静态变量。静态局部变量具有局部作用域,但却具有全局生存期。
  • 静态局部变量具有局部作用域,但却具有全局生存期。也就是说,静态局部变量在程序的整个运行期间都存在,它占据的空间一直到程序结束时才释放,但仅在定义它的块中有效,在块外并不能访问它。
  • 静态变量均存储在全局数据区,静态局部变量只执行一次初始化。如果程序未显式给出初始值,则相当于初始化为0;如果显式给出初始值,则在该静态变量所在块第一次执行时完成初始化。
#include<iostream>
using namespace std;

//全局静态变量
static int glos_s=10;
//全局变量
int glos_a=10;

void f(){
  int a=1; //局部变量a
  static int fs=1; //静态局部变量fs,完成初始化。
  a+=2;
  fs+=2;
  glos_s+=10;
  glos_a+=10;
  cout<<"在f中:局部变量a="<<a<<" 静态局部变量fs="<<fs<<" 全局变量glos_a="<<glos_a<< " 全局静态变量glos_s=" << glos_s <<endl;
}
int main(){
   f(); //在f中:局部变量a=3 静态局部变量fs=3 全局变量glos_a=20 全局静态变量glos_s=20
   f(); //在f中:局部变量a=3 静态局部变量fs=5 全局变量glos_a=30 全局静态变量glos_s=30
  return 0;
}

二、类中的static

1、定义类的静态成员

类的静态成员有两种:静态成员变量和静态成员函数。在类体内定义类的成员时,
在前面添加static关键字后,该成员即成为静态成员。

  • 类的静态成员被类的所有对象共享,不论有多少对象存在,静态成员都只有一份保存在公用内存中。对于静态成员变量,各对象看到的值是一样的。
  • 定义类静态成员变量时,在类定义中声明静态成员变量,然后必须在类体外定义静态成员变量的初值。这个初值不能在类体内赋值。
  • 给静态成员变量赋初值的格式如下:类型 类名::静态成员变量=初值;
  • 注意,在类体外为静态成员变量赋初值时,前面不能加static关键字,以免和一般的静态变量相混淆。在类体外定义成员函数时,前面也不能加static关键字。

2、类静态成员的使用

访问静态成员时,成员前面既可以用类名作前缀,也可以使用对象名或对象指针作前缀。这与访问类成员时仅能使用对象名或对象指针作前缀是不同的。访问类静态成员的一般格式如下:

  • 类名::静态成员名
  • 对象名.静态成员名
  • 对象指针->静态成员名

类的静态成员函数没有this指针,不能在静态成员函数内访问非静态的成员,即通常情况下,类的静态成员函数只能处理类的静态成员变量。静态成员函数内也不能调用非静态成员函数。

#include<iostream>

using namespace std;

class Student{
  public:
    int id;
    string name;
    static int money;
    static void printlnMoney(Student &stu);
};
//静态成员必须在类体外初始化,并且不能在类体内赋值
int Student::money=10000;
//静态成员函数的实现
void Student::printlnMoney(Student &stu){
  cout << "name:" << stu.name <<" money:" << stu.money << endl;
}

int main(){
  Student stu;
  stu.id=1;
  stu.name="小米";
  //使用对象调用静态成员
  stu.printlnMoney(stu);//name:小米 money:10000
  Student *stu2=new Student();
  stu2->id=1;
  stu2->name="美团";
  //使用指针调用静态成员
  stu2->printlnMoney(*stu2);//name:美团 money:10000
  //使用类名调用静态成员
  Student::money=50000;
  Student::printlnMoney(*stu2);//name:美团 money:50000
  Student::printlnMoney(stu);//name:小米 money:50000
  return 0;
}

3、普通成员与静态成员

对于普通成员变量,每个对象有各自的一份,而静态成员变量只有一份,被同类所有对象共享。普通成员函数一定是作用在某个对象上的,而静态成员函数并不具体作用在某个对象上。

访问普通成员时,要通过“对象名.成员名”等方式,指明要访问的成员变量是属于哪个对象的,或要调用的成员函数作用于哪个对象;

访问静态成员时,则可以通过“类名::成员名”的方式访问,不需要指明被访问的成员属于哪个对象或作用于哪个对象。
因此,甚至可以在还没有任何对象生成时就访问一个类的静态成员。非静态成员的访问方式其实也适用于静态成员,也就是可以通过“对象名.成员名”的方式访问,效果和“类名::成员名”这种访问方式没有区别

在通常情况下,除一种情况外,类的成员函数之间是允许互相调用的。具体来说,静态函数与静态函数之间、非静态函数与非静态函数之间是可以相互调用的,非静态成员函数内可以调用静态成员函数,但静态成员函数内不能调用非静态成员函数

以上就是一文读懂c++之static关键字的详细内容,更多关于c++ static关键字的资料请关注我们其它相关文章!

(0)

相关推荐

  • 详解c++中的 static 关键字及作用

    注:若没有特指是 静态成员时,默认都是普通成员: 1 类中的普通成员 类中的成员变量 和 成员函数 是分开存储的.其中, 1)每个对象都有独立的成员变量:成员变量可以存储在 栈空间.堆空间.全局数据区: 2)所有对象共享类的成员函数:成员函数 只能存储在 代码段: 2 类中的静态成员(static) 类中的静态成员 1.用 static关键字 修饰: 2.可以用 类名::成员名 访问 静态成员: 3.静态成员 属于 整个类: 4.静态成员 是所属类的成员,其它类不能访问: 5.静态成员的内存分配

  • C++面试基础之static关键字详解

    前言 static是 c++ 的关键字,顾名思义是表示静态的含义.它在 c++ 中既可以修饰变量也可以修饰函数.那当我们使用 static 时,编译器究竟做了哪些事情呢? 早先面试中被问到 static 关键字,感觉既熟悉又陌生.熟悉是都知道如何去使用它,陌生又来自不知道它究竟对我们程序做了什么.今天就来好好复习下这个关键字,本文的重点也在第三部分. 先看一下示例代码: test1.cpp #include <iostream> extern int a_int; extern void fu

  • C/C++中static,const,inline三种关键字详细总结

    一.关于staticstatic 是C++中很常用的修饰符,它被用来控制变量的存储方式和可见性,下面我将从 static 修饰符的产生原因.作用谈起,全面分析static 修饰符的实质. static 的两大作用: 一.控制存储方式 static被引入以告知编译器,将变量存储在程序的静态存储区而非栈上空间. 引出原因:函数内部定义的变量,在程序执行到它的定义处时,编译器为它在栈上分配空间,大家知道,函数在栈上分配的空间在此函数执行结束时会释放掉,这样就产生了一个问题: 如果想将函数中此变量的值保

  • 关于C/C++中static关键字的作用总结

    1.先来介绍它的第一条也是最重要的一条:隐藏.(static函数,static变量均可)当同时编译多个文件时,所有未加static前缀的全局变量和函数都具有全局可见性.举例来说明.同时编译两个源文件,一个是a.c,另一个是main.c. 复制代码 代码如下: //a.cchar a = 'A';               // global variablevoid msg(){     printf("Hello\n");} 复制代码 代码如下: //main.c int main

  • C++的static关键字及变量存储位置总结

    今天看博文时,看到了c++的static关键字的一些总结,还涉及到了一些代码的存储位置,为了有时间的时候能够看一下,还是自己把它给摘抄下来吧. C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static.前者应用于普通变量和函数,不涉及类:后者主要说明static在类中的作用. 一.面向过程设计中的static 1.静态全局变量 在全局变量前,加上关键字static,该变量就被定义成为一个静态全局变量.我们先举一个静态全局变量的例子,如下: 复制代码 代码

  • C++语言基础 this和static关键字

    一.this关键字 this是一个指针,可用其访问成员变量或成员函数 下面是使用this的一个完整示例: #include <iostream> using namespace std; class Student{ public: void setname(char *name); void setage(int age); void setscore(float score); void show(); private: char *name; int age; float score;

  • 一文读懂c++之static关键字

    一.静态变量 与C语言一样,可以使用static说明自动变量.根据定义的位置不同,分为静态全局变量和静态局部变量. 全局变量是指在所有花括号之外声明的变量,其作用域范围是全局可见的,即在整个项目文件内都有效.使用static修饰的全局变量是静态全局变量,其作用域有所限制,仅在定义该变量的源文件内有效,项目中的其他源文件中不能使用它. 块内定义的变量是局部变量,从定义之处开始到本块结束处为止是局部变量的作用域.使用static修饰的局部变量是静态局部变量,即定义在块中的静态变量.静态局部变量具有局

  • 一文搞懂C语言static关键字的三个作用

    目录 static修饰局部变量 static 修饰全局变量 static 修饰函数 总结 static修饰局部变量 图一:test 函数里面定义的 a 是局部变量,局部变量在栈区上开辟空间,栈区的使用特点是进入变量的生命周期时自动为其开辟空间,离开变量的生命周期时自动销毁对应空间,所以这里每次调用 test 函数时 a 都会被重新定义并初始化为0,所以屏幕上打印的是10个1: 图二:我们把 a 用 static 修饰后发现屏幕打印的是1到10,就好像每次调用完 test 函数后 a 并没有被销毁

  • 一文读懂ava中的Volatile关键字使用

    在本文中,我们会介绍java中的一个关键字volatile. volatile的中文意思是易挥发的,不稳定的.那么在java中使用是什么意思呢? 我们知道,在java中,每个线程都会有个自己的内存空间,我们称之为working memory.这个空间会缓存一些变量的信息,从而提升程序的性能.当执行完某个操作之后,thread会将更新后的变量更新到主缓存中,以供其他线程读写. 因为变量存在working memory和main memory两个地方,那么就有可能出现不一致的情况. 那么我们就可以使

  • 一文读懂Java Iterator(迭代器)

    Java Iterator(迭代器)不是一个集合,它是一种用于访问集合的方法,可用于迭代 ArrayList和HashSet等集合. Iterator 是 Java 迭代器最简单的实现,ListIterator 是 Collection API 中的接口, 它扩展了 Iterator 接口. 迭代器 it 的两个基本操作是 next .hasNext 和 remove. 调用 it.next() 会返回迭代器的下一个元素,并且更新迭代器的状态. 调用 it.hasNext() 用于检测集合中是否

  • 一文读懂c++11 Lambda表达式

    1.简介 1.1定义 C++11新增了很多特性,Lambda表达式(Lambda expression)就是其中之一,很多语言都提供了 Lambda 表达式,如 Python,Java ,C#等.本质上, Lambda 表达式是一个可调用的代码单元[1]^{[1]}[1].实际上是一个闭包(closure),类似于一个匿名函数,拥有捕获所在作用域中变量的能力,能够将函数做为对象一样使用,通常用来实现回调函数.代理等功能.Lambda表达式是函数式编程的基础,C++11引入了Lambda则弥补了C

  • 一文读懂C++ 虚函数 virtual

    探讨 C++ 虚函数 virtual 有无虚函数的对比 C++ 中的虚函数用于解决动态多态问题,虚函数的作用是允许在派生类中重新定义与积累同名的函数,并且可以通过基类指针或引用来访问基类和派生类中的同名函数. 首先写两个简单的类,类 B 继承自类 A,即 A 是基类,B 是派生类. class A{ public: void print(){ cout << "A" << endl; } }; class B : public A { public: void

  • 一文读懂Spring Cloud-Hystrix

    Hystrix概述 Hystrix:断路器,容错管理工具,旨在通过熔断机制控制服务和第三方库的节点,从而对延迟和故障提供更强大的容错能力. hystrix可以实现降级和熔断: 降级 调用远程服务失败(宕机.500错.超时),可以降级执行当前服务中的一段代码,向客户端返回结果 快速失败 熔断 当访问量过大,出现大量失败,可以做过热保护,断开远程服务不再调用 限流 防止故障传播.雪崩效应 在微服务系统中,服务之间进行依赖,避免有调用其中服务失败,而引起其他服务大范围宕机,造成雪崩效应,hystrix

  • 一文读懂Spring Bean的生命周期

    目录 一.前言 1.1 什么是 Bean 1.2 什么是 Spring Bean 的生命周期 二.Spring Bean 的生命周期 三.Spring Bean 的生命周期的扩展点 3.1 Bean 自身的方法 3.2 容器级的方法(BeanPostProcessor 一系列接口) 3.2.1 InstantiationAwareBeanPostProcessor 源码分析 3.2.2 BeanPostProcessor 源码分析 3.3 工厂后处理器方法(BeanFactoryProcesso

  • 一文读懂JAVA中HttpURLConnection的用法

    针对JDK中的URLConnection连接Servlet的问题,网上有虽然有所涉及,但是只是说明了某一个或几个问题,是以FAQ的方式来解决的,而且比较零散,现在对这个类的使用就本人在项目中的使用经验做如下总结: 1:> URL请求的类别: 分为二类,GET与POST请求.二者的区别在于: a:) get请求可以获取静态页面,也可以把参数放在URL字串后面,传递给servlet, b:) post与get的不同之处在于post的参数不是放在URL字串里面,而是放在http请求的正文内. 2:>

  • 一文读懂vue动态属性数据绑定(v-bind指令)

    v-bind的基本用法 一.本节说明 前面的章节我们学习了如何向页面html标签进行插值操作,那么如果我们想动态改变html标签的属性,该怎么办呢? 这就是我们这节开始要讲的内容v-bind. 二. 怎么做 ":"为v-bind的简写形式,也可称为语法糖 三. 效果 四. 深入 在上图中将a标签的href属性值设置为toutiao,VUE实例将自动去data里面寻找toutiao属性进行值绑定. 不只是a标签,所有的html标签属性都可以通过v-bind进行值绑定,然后通过改变数据动态

随机推荐