C++进阶笔记001:static 静态生存期 和 动态生存期
静态和动态 生存期
生存期 :即从诞生到消失的时间段,在生存期内,对象的值保持不变,直到被改变为止。
对象生存期分为 静态生存期 和 动态生存期 两种。
简介
静态生存期:指对象的生存期与程序运行期相同。
动态生存期:可理解为局部对象,诞生于声明点,结束于块执行完毕。
在 namespace
中声明的对象都具有静态生存期,被称为常量。
在函数内部作用域声明的对象具有的都是动态生存期。
函数 静态对象
- 函数内部创建静态对象
如果用 static
修饰,如 static int a
,这个 a 变量就会具有静态生存期,它诞生于第一次执行函数时声明它的位置,然而函数结束时,a 变量并不会消失,会一直存在于函数的这个局部空间中(外部是无法调用的),但是再次执行这个函数时,a 变量并不会在声明 static int a
处被初始化,而是直接调用 a 变量。
示例:
#include <iostream>
using namespace std;void test01()
{int a = 10;a++;cout << "动态生存期a的值为:" << a;
}void test02()
{static int a = 10;a++;cout << "静态生存期a的值为:" << a;
}int main()
{for (int i = 0; i < 5; i++){test01();cout << "\t";test02();cout << endl;}system("pause");return 0;
}
结果:
/*
动态生存期a的值为:11 静态生存期a的值为:11
动态生存期a的值为:11 静态生存期a的值为:12
动态生存期a的值为:11 静态生存期a的值为:13
动态生存期a的值为:11 静态生存期a的值为:14
动态生存期a的值为:11 静态生存期a的值为:15
*/
特点:
在局部作用域中,静态变量的特点是不会随函数的每次调用而产生一个副本,同时也不会因为函数执行完毕而消失;该变量会一直保持上一个值,除非被更改。
- 函数内静态对象的实现原理
将上面的 test02
函数改写成如下形式:
void test02()
{static int a = 10;a++;cout << "静态生存期a的值为:" << a;a = 20;
}
你会发现结果是这样的:
动态生存期a的值为:11 静态生存期a的值为:11
动态生存期a的值为:11 静态生存期a的值为:21
动态生存期a的值为:11 静态生存期a的值为:21
动态生存期a的值为:11 静态生存期a的值为:21
动态生存期a的值为:11 静态生存期a的值为:21
实现原理:
当函数第一次执行时,会加载所有的 static
对象,比如上例,创建了一个 int
类型的 a
变量,并且这个变量是具有静态生存期的,在函数执行完毕前,将 a=20
重定义,会发现,a
变量并没有变为动态对象,因为程序并没有报错,a
如果变成了动态对象,第二次执行函数时,a++
会找不到对象而报错。
结论:
- 函数内部,
static
只会在第一次执行,后续都不会再执行static
语句。 - 函数内部的静态对象可以被赋值,但是对静态对象赋值,不会使它成为动态对象。
类 静态对象
类的静态对象称为静态成员,是解决同一个类的不同对象之间数据和函数的共享问题。
静态成员就是在成员变量和成员函数前加上关键字static
,称为静态成员。
静态成员分为:
- 静态成员变量
- 所有对象共享同一份数据
- 在编译阶段分配内存
- 类内声明,类外初始化
- 静态成员函数
- 所有对象共享一个函数
- 静态成员函数只能访问静态成员变量
如每生成一个对象,则计数+1,从而统计一共创建了多少个对象。
类 创建静态成员变量
和函数类似,如果类中某个属性为整个类所共享,则用 static
修饰为静态成员;该成员在每个类中只有一个副本,由所有对象共同维护,从而实现数据共享。
**注意:**静态数据成员必须在类定义体的外部定义,且只能定义一次。静态数据成员不能通过类的构造函数初始化,而是应该在定义时进行初始化。
保证对象正好定义一次的方法是,将static数据成员的定义放在包含类的非内联成员函数定义的源文件中。
因为静态数据成员不属于任何对象,所以有多种访问方式:
类名::成员名
对象名.成员名
指针->成员名
引用.成员名
示例:
#include <iostream>
using namespace std;class Dog
{public:Dog(string name){name = name;count ++;}static int count;
private:string name;
};// 初始化类静态成员
int Dog::count = 0;int main()
{Dog dog01("Sherry");Dog dog02("Henry");cout << "现在有 " << Dog::count << " 只狗:" << endl;system("pause");return 0;
}
再次注意: 不要将静态成员的定义放在头文件中,除非你能保证该头文件不会被两个不同的源文件包含,不然会报重复定义错误,相当于是在两个源文件中都定义了同一个变量。对于这种同一头文件被不同源文件包含的情况,使用 #ifndef
或者 #pragma once
是没用的。这种预编译宏是为了解决一个源文件两次包含同一个头文件的问题。
同时,对静态数据成员的定义也不能放在main()函数里,否则编译报错:error C2655: “Box::height”: 当前范围内的定义或重新声明非法
。
正确的做法,就如上面所说,把它放在定义类的成员函数的源文件中。
类 创建静态成员函数
#include <iostream>
using namespace std;class Dog
{public:Dog(string name){m_name = name;count ++;}static void func(){ count = 0;// 静态函数 只能调用 静态变量// m_name = "Sunshine";cout << "static void func 调用" << endl;}static int count;
private:string m_name;
};// 初始化类静态成员
int Dog::count = 0;int main()
{Dog dog01("Sherry");Dog dog02("Henry");dog02.func();cout << "现在有 " << Dog::count << " 只狗:" << endl;system("pause");return 0;
}
注意:
- 静态成员函数 只能访问 静态成员变量
C++进阶笔记001:static 静态生存期 和 动态生存期相关推荐
- 静态生存期和动态生存期
静态生存期 定义: 如果某一个对象的生存期和程序的运行的生存期一样,则这个对象具有静态生存期. 关键字:static 特点 静态变量不会随着每次函数的调用产生一个新的副本,也不会随着函数返回而失效.第 ...
- c++对象的生存期 静态生存期和动态生存期
在线学堂 郑莉 第五章 数据的共享和保护 第三节 类的生存期
- 程序员麦兜【编程笔记】-Java静态代理与动态代理
------代理模式 为其他对象提供一种代理以控制对这个对象的访问.比如A对象要做一件事情,在没有代理前,自己来做.在对A代理后,由A的代理类B来做. ------静态代理的原理 静态代理说白了,就是 ...
- 【PyTorch 】静态图与动态图机制
[PyTorch 学习笔记] 1.4 静态图与动态图机制 - 知乎 PyTorch 的动态图机制 PyTorch 采用的是动态图机制 (Dynamic Computational Graph),而 T ...
- C++静态库与动态库详解与使用
福利 | 百度 AI 开发者大会免费门票领取 CSDN日报20170628--<实习,背后的选择?> [直播]探究Linux的总线.设备.驱动模型! C++静态库与动态库详解与 ...
- 第20天学习Java的笔记-static静态
28天 静态static关键字 1.概述 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1rR1rotO-1608259503514)(F:\Java\Learn\da ...
- Static静态---笔记A
package objectOriented; public class StaticA { * @param args * static静态:(共享数据) * 是一个修饰符,用于 ...
- 小啊呜产品读书笔记001:《邱岳的产品手记-14》第26讲 写好产品文档的诀窍 第27讲 产品案例分析: QuartzHooked的对话式交互
小啊呜产品读书笔记001:<邱岳的产品手记-14>第26讲 写好产品文档的诀窍 & 第27讲 产品案例分析: Quartz&Hooked的对话式交互 一.今日阅读计划 二. ...
- 小啊呜产品读书笔记001:《邱岳的产品手记-12》第22讲 产品经理的图文基本功(上):产品文档 23讲产品经理的图文基本功(下):产品图例
小啊呜产品读书笔记001:<邱岳的产品手记-12>第22讲 产品经理的图文基本功(上):产品文档 & 23讲产品经理的图文基本功(下):产品图例 一.今日阅读计划 二.泛读& ...
最新文章
- SQL SERVER数据页checksum校验算法
- 再谈应用环境下的TIME_WAIT和CLOSE_WAIT
- pandas库简单入门
- LUA 拾遗(编译-调试-运行)
- 背包问题 小灰_小背包问题
- 安装了多个Oracle11g的客户端,哪个客户端的tnsnames.ora会起作用?
- 人口简史:我们曾经差一点就彻底没了
- 用几何语言表示线段ab的中点c,做完这30道精选题,你的几何图形绝对满分!
- 如何在Spring MVC工程中进行单元测试
- V4L2抓取USB摄像头YUV视频数据代码
- 手机电子书UMD数据格式实现代码(C#版)
- android计算器表格布局,Android 计算器UI-TableLayout
- Adaptable and Adaptive Hypermedia Systems
- 如何下载视频号的视频
- 联想进入bios修复计算机,联想笔记本安装win10后开启界面一直是自动修复,进不了BIOS重装系统...
- 用机械键盘敲代码会不会更带感 ?送 9 套雷柏机械键盘
- 竟还有如此搞笑的代码注释,我笑喷了
- vue_2.0_fyf
- “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛(同步赛)---全题目+题解
- Uber 时序数据库M3DB初探