生存期,即从诞生到消失的时间段,在生存期内,对象的值或保持不变,知道改变他的值为止。对象生存期分为静态生存期动态生存期两种。

  • 静态生存期

指对象的生存期与程序运行期相同。在namespace中声明的对象都具有静态生存期。但是,在函数内部作用域中声明具有动态生存期的对象,要用static修饰,如static int a。

在局部作用域中,静态变量的特点是不会随函数的每次调用而产生一个副本,同时也不会因为函数的返回而消失。该变量会一直保持上一个值,在每次调用中可共享。同时静态变量在定义时也可以赋值,如static int a = 3;

  • 动态生存期

除上述两种情况,其余为动态生存期。在局部作用域中,有动态生存期的对象,也称为局部生存期对象。局部生存期对象诞生于声明点,结束于声明块执行完毕。在类中不用static修饰的成员,他们的生存期和对象生存期一致。

例:

#include<iostream>
using namespace std;
int i =1;//i全局变量,动态生存期
void Other()
{
static int a = 2;
static int b ;//a,b为静态局部变量,全局寿命,局部可见,第一次进入函数时初始化
int c = 10;//c局部变量,动态生存期,每次进入函数都初始化
a+=2;
i+=32;
c+=5;
cout<<"Other:"<<endl;
cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
}
int main()
{
static int a;//静态局部变量,全局寿命,局部可见
int b= -1;
int c = 0;;//b,c局部变量,动态生存期
cout<<"Main:"<<endl;
cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
c+=8;
Other();
cout<<"Main:"<<endl;
cout<<"i: "<<i<<" a: "<<a<<" b: "<<b<<" c: "<<c<<endl;
i+=10;
Other();
return 0;
}

  运行结果


类的静态成员

类的静态成员是解决同一个类的不同对象之间数据和函数的共享问题的。如每生成一个对象,则计数+1,从而统计一共创建了多少个对象。

  • 静态数据成员

在类的一个属性中,如果某个属性为整个类所共享,则用static修饰为静态成员。该成员在每个类中只有一个副本,由所有对象共同维护,从而实现数据共享。

静态数据成员具有静态生存期,因为静态数据成员不属于任何对象,可以这么访问,”类名::成员名  |  对象名.成员名  |  指针->成员名 | 引用.成员名“ 。另外,在类定义中,仅进行引用性声明,而在namespace作用域中使用类名限定定义性声明,或初始化。(原因:这样定义是因为这种方式要专门分配空间,非静态数据成员的空间与所属对象空间是同时分配的,所以无须这样定义)。

例:

#include<iostream>
using namespace std;
class Point
{
public:
Point(int x = 0,int y = 0):x(x),y(y)
{
count++;
}
Point(Point &p)//copy
{
x = p.x;
y = p.y;
count++;
}
~Point()
{
count --;
}
int GetX(){return x;}
int GetY(){return y;}
void ShowCount()//静态函数
{
cout<<"Object count :"<<count<<endl;
}
private:
static int count;//static
int x;
int y;
}; int Point:: count = 0;//静态数据成员的初始化,类名限定 int main()
{
Point a(4,5);
cout<<"Pont a:"<<"("<<a.GetX()<<","<<a.GetY()<<")"<<endl;
a.ShowCount();//通过对象名
Point b(a);
cout<<"Pont b:"<<"("<<b.GetX()<<","<<b.GetY()<<")"<<endl;
b.ShowCount();
return 0;
}

  运行结果

  • 静态函数成员

在上面例子中,ShowCount()是输出count的值的,而在所有对象声明前,count是==0的,那么如果输出这时的count,该怎么做??所以这时静态函数成员就起作用了。

修改如下:

class Point
{
public:
.
.
.
static void ShowCount()//静态函数
{
cout<<"Object count :"<<count<<endl;
}
private:
...
}; int Point:: count = 0;//静态数据成员的初始化,类名限定
int main()
{
Point::ShowCount();
Point a(4,5);
cout<<"Pont a:"<<"("<<a.GetX()<<","<<a.GetY()<<")"<<endl;
Point::ShowCount();
Point b(a);
cout<<"Pont b:"<<"("<<b.GetX()<<","<<b.GetY()<<")"<<endl;
Point::ShowCount();
return 0;
}

  运行结果

在ShowPoint()函数前加一个static,即变为静态成员函数,它也属于整个类,有所有对象共同拥有,为所有对象共享。静态成员函数可以用过类名|对象名访问,非静态成员函数只能通过对象名调用。

另外,静态成员函数可以直接访问类的静态数据和函数成员,而访问非静态成员,必须通过对象名。所以一般情况下,静态函数用来访问类的静态数据成员。

C++对象生存期&&static的更多相关文章

  1. 从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结

    一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...

  2. 四种对象生存期和作用域、static 用法总结

    一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...

  3. php笔记(二)PHP类和对象之Static静态关键字

      PHP类和对象之Static静态关键字 静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用.静态属性不允许对象使用->操作符调用. class Car { pr ...

  4. 基础学习day06---面向对象二---static,类的初始化和调用顺序、单例模式

    一.static关键字 1.1.static关键字 静态:static用法:是一个修饰符,用于修饰成员(成员变量,成员函数)static 修饰的内容,所有对象共享当成员被静态修饰后,就多了一个调用方式 ...

  5. JavaSE入门学习12: Java面相对象之static使用方法

    我们能够基于一个类创建多个该类的对象,每一个对象都拥有自己的成员,互相独立. 然而在某些时候,我们更希 望该类全部的对象共享同一个成员. 此时就是static大显身手的时候了. Java中被stati ...

  6. jvm源码解读--09 创建oop对象,将static静态变量放置在oop的96 offset处 第二篇

    先打断点systemDictionary.cpp 1915行 Universe::fixup_mirrors(CHECK); 进入 void Universe::fixup_mirrors(TRAPS ...

  7. 【java】学习路线5-public和private、构造方法、this关键字、封装对象、static关键字、main方法结构解析

    //一个教务管理系统//知识点清单/*public & private 的区别一个是公开的,一个是私有的,作用域不一样,访问的权限不一样咯如果是用private修饰,则调用者只可以是在当前的作 ...

  8. java学习-初级入门-面向对象⑥-类与对象-静态static

    这次我们来学习静态(static) 知识点 1.静态方法只能调用静态变量 2.静态变量属于整个Class,会随着发生变化. 案例:定义一个自动增长的学生类. 题目要求: 定义一个学生类,除了姓名.性别 ...

  9. jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处

    之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...

随机推荐

  1. HTTP协议简单记录

    http协议的格式 1. 首行 2. 头 3. 空行 4. 体 http请求头 #Referer 请求来自哪里,如果是在http://www.baidu.com上点击链接发出的请求,那么Referer ...

  2. 数据结构和算法总结(一):广度优先搜索BFS和深度优先搜索DFS

    前言 这几天复习图论算法,觉得BFS和DFS挺重要的,而且应用比较多,故记录一下. 广度优先搜索 有一个有向图如图a 图a 广度优先搜索的策略是: 从起始点开始遍历其邻接的节点,由此向外不断扩散. 1 ...

  3. JAVA中写时复制(Copy-On-Write)Map实现

    1,什么是写时复制(Copy-On-Write)容器? 写时复制是指:在并发访问的情景下,当需要修改JAVA中Containers的元素时,不直接修改该容器,而是先复制一份副本,在副本上进行修改.修改 ...

  4. PAT1040:Longest Symmetric String

    1040. Longest Symmetric String (25) 时间限制 400 ms 内存限制 65536 kB 代码长度限制 16000 B 判题程序 Standard 作者 CHEN, ...

  5. 【线程系列五】什么时候释放锁—wait()、notify()

    由于等待一个锁定线程只有在获得这把锁之后,才能恢复运行,所以让持有锁的线程在不需要锁的时候及时释放锁是很重要的.在以下情况下,持有锁的线程会释放锁:    1. 执行完同步代码块.    2. 在执行 ...

  6. Vue数据双向绑定原理及简单实现

    嘿,Goodgirl and GoodBoy,点进来了就看完点个赞再go. Vue这个框架就不简单介绍了,它最大的特性就是数据的双向绑定以及虚拟dom.核心就是用数据来驱动视图层的改变.先看一段代码. ...

  7. JavaScript 异步开发全攻略(转)

    写了一本介绍 JavaScript 异步开发的小书: https://meathill.gitbooks.io/javascript-async-tutorial/content/ 除了比较详细的介绍 ...

  8. remove方法

    1.jQuery的remove()方法 http://www.365mini.com/page/jquery-remove.htm ①返回值是jquery对象本身 所以可以做删除再添加的操作 // 移 ...

  9. linux下怎么样上传下载文件夹

    Linux下目录复制:本机->远程服务器 scp -r /home/shaoxiaohu/test1 zhidao@192.168.0.1:/home/test2 test1为源目录,test2 ...

  10. Java 学习笔记 (二) Selenium WebDriver Java 弹出框

    下面这段实例实现了以下功能: 1. profile使用用户本地电脑上的 (selenium 3有问题.因为selenium 3把profile复制到一个temp文件夹里,但并不复制回去.所以每次打开仍 ...