C++对象生存期&&static
生存期,即从诞生到消失的时间段,在生存期内,对象的值或保持不变,知道改变他的值为止。对象生存期分为静态生存期和动态生存期两种。
- 静态生存期
指对象的生存期与程序运行期相同。在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的更多相关文章
- 从零开始学C++之对象的使用(二):四种对象生存期和作用域、static 用法总结
一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...
- 四种对象生存期和作用域、static 用法总结
一.四种对象生存期和作用域 栈对象 隐含调用构造函数(程序中没有显式调用) 堆对象 隐含调用构造函数(程序中没有显式调用),要显式释放 全局对象.静态全局对象 全局对象的构造先于main函数 已初始化 ...
- php笔记(二)PHP类和对象之Static静态关键字
PHP类和对象之Static静态关键字 静态属性与方法可以在不实例化类的情况下调用,直接使用类名::方法名的方式进行调用.静态属性不允许对象使用->操作符调用. class Car { pr ...
- 基础学习day06---面向对象二---static,类的初始化和调用顺序、单例模式
一.static关键字 1.1.static关键字 静态:static用法:是一个修饰符,用于修饰成员(成员变量,成员函数)static 修饰的内容,所有对象共享当成员被静态修饰后,就多了一个调用方式 ...
- JavaSE入门学习12: Java面相对象之static使用方法
我们能够基于一个类创建多个该类的对象,每一个对象都拥有自己的成员,互相独立. 然而在某些时候,我们更希 望该类全部的对象共享同一个成员. 此时就是static大显身手的时候了. Java中被stati ...
- jvm源码解读--09 创建oop对象,将static静态变量放置在oop的96 offset处 第二篇
先打断点systemDictionary.cpp 1915行 Universe::fixup_mirrors(CHECK); 进入 void Universe::fixup_mirrors(TRAPS ...
- 【java】学习路线5-public和private、构造方法、this关键字、封装对象、static关键字、main方法结构解析
//一个教务管理系统//知识点清单/*public & private 的区别一个是公开的,一个是私有的,作用域不一样,访问的权限不一样咯如果是用private修饰,则调用者只可以是在当前的作 ...
- java学习-初级入门-面向对象⑥-类与对象-静态static
这次我们来学习静态(static) 知识点 1.静态方法只能调用静态变量 2.静态变量属于整个Class,会随着发生变化. 案例:定义一个自动增长的学生类. 题目要求: 定义一个学生类,除了姓名.性别 ...
- jvm源码解读--08 创建oop对象,将static静态变量放置在oop的96 offset处
之前分析的已经加载的.Class文件中都没有Static 静态变量,所以也就没这部分的解析,自己也是不懂hotspot 将静态变量放哪里去了,追踪源码之后,看清楚了整个套路,总体上来说,可以举例来说对 ...
随机推荐
- (Lesson2)根据类名称和属性获得元素-JavaScript面向对象
描述:在编写选择器的时候遇到的一根问题,我需要实现Jquery的选择器功能,第一个根据ID获取Element非常简单,第二个根据类(class)去获取Element集合,这个相对复杂,而根据name和 ...
- Axios源码深度剖析 - 替代$.ajax,成为xhr的新霸主
前戏 在正式开始axios讲解前,让我们先想想,如何对现有的$.ajax进行简单的封装,就可以直接使用原声Promise了? let axios = function(config){ return ...
- 基于Kafka Connect框架DataPipeline可以更好地解决哪些企业数据集成难题?
DataPipeline已经完成了很多优化和提升工作,可以很好地解决当前企业数据集成面临的很多核心难题. 1. 任务的独立性与全局性. 从Kafka设计之初,就遵从从源端到目的的解耦性.下游可以有很多 ...
- MySQL类型float double decimal的区别
语法 MySQL 浮点型和定点型可以用类型名称后加(M,D)来表示,M表示该值的总共长度,D表示小数点后面的长度,M和D又称为精度和标度,如float(7,4)的 可显示为-999.9999,MySQ ...
- Python初级教程
Python语言的特点 优点: - 简单 - 易学 - 免费,开源 - 高层语言 - 可移植性(可再多平台运行) - 解释性(不需要编译,可直接运行) - 面向对象 - 可扩展性(缺点:运行效率相对较 ...
- 【手记】解决启动SQL Server Management Studio 17时报Cannot find one of more components...的问题
刚装好SSMS 17.1准备体验,弹出: 一番搜索,普遍办法都是安装VS2015独立shell.删除某个注册表项什么的,没用,首先这个shell我是装了的,然后也没有那个注册表项.我自己尝试过重装sh ...
- web页面测试
一.Web的功能测试 1.超链接测试 a.链接与链接的说明文字要匹配 (注:也可以是图片) b.链接的文字要描述正确 c.链接的文字要精简有效 d.链接 ...
- Cookie防篡改机制
一.为什么Cookie需要防篡改 为什么要做Cookie防篡改,一个重要原因是 Cookie中存储有判断当前登陆用户会话信息(Session)的会话票据-SessionID和一些用户信息. 当发起一个 ...
- python实现简体中文和繁体相互转换
1. opencc-python 如果目录上的链接被屏蔽了,请手动复制 https://pypi.python.org/pypi/opencc-python/ 首先介绍opencc的python实现库 ...
- Python实现控制台密码星号输入
import msvcrt, sys, os print('password: ', end='', flush=True) li = [] while 1: ch = msvcrt.getch() ...