C++类静态数据成员与类静态成员函数
from:://http://blog.csdn.net/taina2008/article/details/1684834
把类中的函数都定义成静态函数,这样相当于在编译时就分配了空间,这样不需要实体对象也可以调用泪中的函数了。
C++类静态数据成员与类静态成员函数
我们如何才能在类范围内共享数据呢?
这个问题便是本章的重点:
声明为static的类成员或者成员函数便能在类的范围内共同享,我们把这样的成员称做静态成员和静态成员函数。
下面我们用几个实例来说明这个问题,类的成员需要保护,通常情况下为了不违背类的封装特性,我们是把类成员设置为protected(保护状态)的,但是我们为了简化代码,使要说明的问题更为直观,更容易理解,我们在此处都设置为public。
以下程序我们来做一个模拟访问的例子,在程序中,每建立一个对象我们设置的类静态成员变自动加一,代码如下:
#include <iostream>
using namespace std;
class Internet
{
public:
Internet(char *name,char *address)
{
strcpy(Internet::name,name);
strcpy(Internet::address,address);
count++;
}
static void Internet::Sc()//静态成员函数,静态函数必须在类体内实现
{
cout<<count<<endl;
}
Internet &Rq();
public:
char name[20];
char address[20];
static int count;//这里如果写成static int count=0;就是错误的
};
Internet& Internet::Rq()//返回引用的成员函数
{
return *this;
}
int Internet::count = 0;//静态成员的初始化
void vist()
{
Internet a1("中国软件开发实验室","www.cndev-lab.com");
Internet a2("中国软件开发实验室","www.cndev-lab.com");
}
void fn(Internet &s)
{
cout<<s.Rq().count;
}
void main()
{
cout<<Internet::count<<endl;//静态成员值的输出
vist();
Internet::Sc();//静态成员函数的调用
Internet b("中国软件开发实验室","www.cndev-lab.com");
Internet::Sc();
fn(b);
cin.get();
}
上面代码我们用了几种常用的方式建立对象,当建立新对象并调用其构造函数的时候,静态成员cout便运行加1操作,静态成员的初始化应该在主函数调用之 前,并且不能在类的声明中出现,通过运行过程的观察我们发现,静态成员count的状态并不会随着一个新的对象的新建而重新定义,尽而我们了解到类的静态成员是属于类的而不是属于哪一个对象的,所以静态成员的使用应该是类名称加域区分符加成员名称的,在上面的代码中就是Internet::count,虽然我们仍然可以使用对象名加点操作符号加成员名称的方式使用,但是不推荐的,静态态类成员的特性就是属于类而不专属于某一个对象。
静态成员函数的特性类似于静态成员的使用,同样与对象无关,调用方法为类名称加域区分符加成员函数名称,在上面的代码中就是Internet::Sc();,静态成员函数由于与对象无关系,所以在其中是不能对类的普通成员进行直接操作的。
如果上面的 static void Internet::Sc()修改成为:
static void Internet::Sc()//静态成员函数
{
cout<<name<<endl;//错误
cout<<count<<endl;
}
静态成员函数与普通成员函数的差别就在于缺少this指针,没有这个this指针自然也就无从知道name是哪一个对象的成员了。
根据类静态成员的特性我们可以简单归纳出几点,静态成员的使用范围:
1.用来保存对象的个数。
2.作为一个标记,标记一些动作是否发生,比如:文件的打开状态,打印机的使用状态,等等。
3.存储链表的第一个或者最后一个成员的内存地址。
为了做一些必要的练习,深入的掌握静态对象的存在的意义,我们以前面的结构体的教程为基础,用类的方式描述一个线性链表,用于存储若干学生的姓名,代码如下:
#include <iostream>
using namespace std;
class Student
{
public:
Student (char *name);
~Student();
public:
char name[30];
Student *next;
static Student *point;
};
Student::Student (char *name)
{
strcpy(Student::name,name);
this->next=point;
point=this;
}
Student::~Student ()//析构过程就是节点的脱离过程
{
cout<<"析构:"<<name<<endl;
if(point==this)
{
point=this->next;
cin.get();
return;
}
for(Student *ps=point;ps;ps=ps->next)
{
if(ps->next==this)
{
cout<<ps->next<<"|"<<this->next<<endl;
ps->next=next;//=next也可以写成this->next;
cin.get();
return;
}
}
cin.get();
}
Student* Student::point=NULL;
void main()
{
Student *c = new Student("marry");
Student a("colin");
Student b("jamesji");
delete c;
Student *fp=Student::point;
while(fp!=NULL)
{
cout<<fp->name<<endl;
fp=fp->next;
}
cin.get();
}
从上面的代码来看,原来单纯结构化编程需要的一个链表进入全局指针在这里被类的静态成员指针所替代(类的静态成员完全可以替代全局变量),这个例子的理解重点主要是要注意观察类成员的析构顺序,通过对析构顺序的理解,使用析构函数来进行节点的脱链操作。
C++类静态数据成员与类静态成员函数的更多相关文章
- 《挑战30天C++入门极限》C++类静态数据成员与类静态成员函数
C++类静态数据成员与类静态成员函数 在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? ...
- 如何导出标准模板库(STL)类的实例化和包含STL类对象数据成员的类
本文翻译自 https://support.microsoft.com/zh-cn/help/168958/how-to-export-an-instantiation-of-a-standard-t ...
- C++中static修饰的静态成员函数、静态数据成员
1.静态成员函数.静态数据成员 在类中,用static修饰的成员函数被称为静态成员函数,而用static修饰的数据成员就称为静态数据成员:与普通的成员函数和数据成员不同, 静态成员函数和静态数据成员有 ...
- C++学习5-面向对象编程基础(构造函数、转换构造、静态数据成员、静态成员函数、友元)
知识点学习 类 const作用 C语言的const限定符的含义为"一个不能改变值的变量",C++的const限定符的含义为"一个有类型描述的常量": const ...
- C++ 静态数据成员和静态成员函数
一 静态数据成员: 1.静态数据成员的定义. 静态数据成员实际上是类域中的全局变量.所以,静态数据成员的定义(初始化)不应该被放在头文件中,因为这样做会引起重复定义这样的错误.即使加上#ifndef ...
- C++基础(静态数据成员和静态成员函数)
[简介] 1.静态数据成员在类中声明,在源文件中定义并初始化: 2.静态成员函数没有this指针,只能访问静态数据成员: 3.调用静态成员函数:(1)对象.(2)直接调用: 4.静态成员函数的地址可用 ...
- 转:C语言中的static变量和C++静态数据成员(static member)
转自:C语言中的static变量和C++静态数据成员(static member) C语言中static的变量:1).static局部变量 a.静态局部变量在函数内定义,生存期为整个程序 ...
- C++类中的常数据成员和静态数据成员的区别
刚开始学习C++的类和对象的部分,对类中的常数据成员和静态数据成员的概念和用法经常混淆,所以今天整理一下,顺便说一下,今天是我的生日,祝我生日快乐,呵呵. 常数据成员 常数据成员是指在类中定义的不能修 ...
- 一个类的实例化对象所占空间的大小(对象大小= vptr(可能不止一个) + 所有非静态数据成员大小 + Aligin字节大小(依赖于不同的编译器))
注意不要说类的大小,是类的对象的大小. 首先,类的大小是什么?确切的说,类只是一个类型定义,它是没有大小可言的. 用sizeof运算符对一个类型名操作,得到的是具有该类型实体的大小. 如果 Class ...
随机推荐
- 在局域网内实现https安全访问
在局域网内实现https安全访问 准备原料 服务器 resin (当然也可以是tomcat,这里以resin为例) 安装jdk 域名 (随便写一个就行,因为是内网使用,不会被校验) 生成证书 第一步: ...
- python2.x下pip install mysql-python报错解决办法
在https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python 下载该驱动网盘链接:https://pan.baidu.com/s/1r0fNYnU ...
- 线上SQL优化
最近在线上发现很多性能有问题的sql,开发写sql语句的时候,没充分考虑是否用上索引了,所以这个坑得DBA来填,好了,废话不多说,把一些线上的优化经验跟大家分享. 由于是线上的表,所以就不公开具体的表 ...
- HttpClient 详解一《C#高级编程(第9版)》
1.异步调用 Web 服务 static void Main(string[] args) { Console.WriteLine("In main before call to GetDa ...
- 第四届CCF软件能力认证
1.图像旋转 问题描述 旋转是图像处理的基本操作,在这个问题中,你需要将一个图像逆时针旋转90度. 计算机中的图像表示可以用一个矩阵来表示,为了旋转一个图像,只需要将对应的矩阵旋转即可. 输入格式 输 ...
- Git(一)Git的简介安装
一.git历史 同生活中的许多伟大事件一样,Git 诞生于一个极富纷争大举创新的年代.Linux 内核开源项目有着为数众广的参与者.绝大多数的 Linux 内核维护工作都花在了提交补丁和保存归档的繁琐 ...
- 记2013年度成都MVP社区巡讲
上个周六在天府软件园A区的翼起来咖啡举行了MVP社区巡讲成都站的活动,这个巡讲活动去年也搞过一次. MVP社区巡讲是 @微软中国MVP项目组 支持的,由各地的MVP担任讲师,给本地技术社区提供的一种社 ...
- free命令中buffers和caches的区别
一.命令 1 2 3 4 5 [root@localhost ~]# free -m total used free shared bu ...
- vue播放video插件vue-video-player实现hls, rtmp播放全过程
1.安装插件 1 npm install vue-video-player -S 2.配置插件 在main.js里添加 1 import VideoPlayer from 'vue-video-pla ...
- java线程中断的办法
目录 中断线程相关的方法 中断线程 for循环标记退出 阻塞的退出线程 使用stop()方法停止线程 中断线程相关的方法 中断线程有一些相应的方法,这里列出来一下. 注意,如果是Thread.meth ...