静态类成员包括静态数据成员和静态函数成员两部分。
与全局变量相比,优势:
1. 静态数据成员仍然是在类域名字空间,没用进入程序的全局名字空间,因此不存在与程序中其他全局名字冲突的可能
2. 可以实现信息隐藏,静态数据成员可以是private成员,全局变量不行
静态数据成员:
静态数据成员必须在类定义外初始化,但const静态数据成员除外,const静态数据成员可以在类体中初始化
class c1
{
public:
private:
static int num;
static const string name = "chio";
};
int c1::num = 20;//类外定义并且初始化
const string c1::name ; //仍然需要在类体外定义
静态数据成员被 类 的所有对象所共享,包括该类派生类的对象。即派生类对象与基类对象共享基类的静态数据成员。
静态成员函数:
类成员函数(无论是static成员函数或非static成员函数)都可以直接访问static数据成员,但是static成员函数只能访问static数据成员。因为静态成员函数不含this指针。
non static member是属于对象级成员函数,也就是说,每个属于该类的对象都会产生一份属于自己的成员。而static member是属于类级成员,也就是说,无论该类产生多少个对象,而这种成员只会产生一个。为什么static member function只能访问static member data呢?就是因为static member data是属于类级成员数据,non static member data是属于对象级成员数据,而static member function是属于类级成员函数,non static member function是属于对象级成员函数。对于一个类级成员函数只能访问到类级成员数据。因为类级成员是共享的,而对象级成员是私有的,私有的数据只能是由私有函数来读取(可不要把这里的共享与私有的关系和灰的声明中的public与private的关系混淆了啊,这里的私有是指对象私有,而后者是指类私有)。
如果对于上面的解释还是不太好理解为什么类级成员只能访问类级成员数据的话,那我就用实际来告诉你为什么私有的对象数据不能由共享的函数来存取了。如有以下类的声明: private : 如果有以下函数的定义: 因为ptA和ptB都会产生属于对象自己的m_x(如果定义更多Point的对象,将会产生更多)。对于OutPut()是毫无疑问没问题的,因为ptA和ptB也会产生属于自己OutPut(),对象自己的函数访问属于对象自己数据,这是理所当然的。但Init()只会产生一个,而ptA和ptB都有属于自己m_x(各自互不侵犯),Init()怎么知道应该访问那个m_x呢(准确点应该说编译器怎么知道应该访问那个的m_x),还是对于所有Point的对象的m_x都进行存取呢(那不就是侵犯私隐了吗)。 正如前面所述的,ptA和ptB都会产生属于自己OutPut(),编译器怎么知道应该调用那个对象的OutPut()呢,对象级的函数自然只能使用对象级的调用方法了。对于Init()却是很好理解的,因为Init()由始至终只有一个,无论类级的调用,还是对象级的调用,都是合情合理的。 类的静态成员是属于类的而不是属于哪一个对象的,所以静态成员的使用应该是类名称加域区分符加成员名称的,在上面的代码中就是Point::Init,虽然我们仍然可以使用对象名加点操作符号加成员名称的方式使用,但是不推荐的,静态态类成员的特性就是属于类而不专属于某一个对象。
静态数据成员可以成为成员函数的可选参数,而普通数据成员则不可以: class base{ static数据成员的类型可以是其所属类,而非static数据成员类型只允许为该类的指针或引用:
class base{
class Point
{
public :
void OutPut ();
static void Init ( int, int );
int m_x;
static int m_y;
};
int Point::m_y = 10; //初始化static member data
Point ptA, ptB;
void
Point::OutPut () //正确
{
cout <<"x=" <<x <<endl
<<"y=" <<y <<endl;
}
void
Point::Init ( int x, int y )
{
m_x = x; //错误,m_x是对象级成员数据,Init()是类级成员函数
m_y = y; //正确,m_y和Init()都是类级成员
}
我们会经常以“类名::类成员函数”这种方法来调用一个函数(当然我不是说只有MFC都有这样的调用)。要使用这样的调用方法是需要有一个条件的,就是这个类成员函数一定要是一个static member function。如果你不明白前面的解释的话,你是不会想到这点的。那为什么一定要是static member function才能这样被调用呢,其实原理跟前面是一样的,就是因为static member function只会产生一个。如果你还是想不到为什么的话,那我就用实际来说明一切吧!沿用前面类的声明,如果有以下的用法:
Point::Init ( 5, 5 ); //正确(这里只讨论它的调用方法,不讨论它的定义是否正确),因为Init()是类级成员函数
ptA.Init ( 3, 3 ); //正确,既然Init()是共享的,ptA自然也可以用
Point::OutPut (); //错误,OutPut()是对象级成员函数
ptA.OutPut (); //正确,对象级的函数调用
public :
static int _staticVar;
int _var;
void foo1(int i=_staticVar);//正确,_staticVar为静态数据成员
void foo2(int i=_var);//错误,_var为普通数据成员 //_var不能独立于所属对象而使用。
};
2 {
3 public
4 //
5 private:
6 static Bar mem1;//ok
7 Bar *mem2;//ok
8 Bar mem3; //error
9 };
静态成员函数不可以同时声明为 virtual、const、volatile函数:
virtual static void func1();//错误
static void func2() const;//错误
static void func3() volatile;//错误
};
只在类体的函数声明前加static, 类体外函数定义不能指定关键字static
发表评论
-
set容器的反向迭代器
2013-05-02 16:56 3673#include <iostream> #in ... -
对于CRITICAL_SECTION用法的介绍和理解[转]
2013-04-08 11:50 2088很多人对CRITICAL_SECTION ... -
二维数组知识
2012-09-15 17:20 767二维数组和指针⑴ 用 ... -
Realloc的使用
2012-08-14 11:04 780realloc 用过很多次了。 ... -
extern C的由来
2012-08-09 10:14 661时常在cpp的代码之中看到这样的代码: #ifdef ... -
C++类对象的创建过程
2012-07-26 16:02 890分配空间(Allocation) ... -
复制构造函数(拷贝构造函数)以及深浅拷贝
2012-07-25 22:39 1385对于普通对象而言复制是很简单的,一般是将变量或者常量赋值给某 ... -
cin、cin.get、cin.getline()、getline()、gets()的用法【转】
2012-07-24 20:05 777学C++的时候,这几个输入函数弄的有点迷糊;这里做个小结,为了 ... -
编程笔记(07-24)
2012-07-24 15:15 6221 #include < stdio.h ... -
堆、栈解疑
2012-07-12 21:53 533一、预备知识—程序的内存分配 一个由C/C++编译的程序 ... -
指针和内存分配的深度理解
2012-07-12 18:57 979一 :关于指针和堆的内存分配 先来介绍一下指针: 指针一种 ... -
数组指针和指针数组
2012-07-12 18:56 1130先看一下基本的形式,我们从这里起步! ----------- ... -
const指针和指向const的指针
2012-07-12 10:30 2068指向const对象的指针 ... -
typedef的学习
2012-07-11 15:03 664typedef,顾名思义,为“类型定义”,可以解释为:将一种数 ... -
函数指针和指针函数
2012-07-11 11:21 531【函数指针】 ... -
Define学习
2012-07-11 10:12 1003宏替换是C/C++系列语言的技术特色,C/C++语言提 ... -
sizeof 深研
2012-07-11 09:39 6331、什么是sizeof 首先看一下sizeof ... -
内存对齐问题
2012-07-10 22:35 10411.内存数据对齐的原因: 无论如何,为了提高程序的性 ... -
指针深究
2012-07-09 21:55 538在说指向指针的指针之前,不得不说指向变量的指针。先看如下示例: ... -
C语言文件使用方式详解
2012-07-04 10:23 707文件的打开(fopen函数) f ...
相关推荐
C++类中的静态成员变量和静态成员函数的作用
C++类与对象:static静态数据成员静态成员函数.doc
静态数据成员函数与子对象,定义一个圆类……………………
1.编写一个类,声明一个数据成员和一个静态数据成员,其构造函数初始化数据成员,并把静态数据成员加1,其析构函数把静态数据成员减1。 (1) 编写一个应用程序,创建该类的3个对象,然后显示其数据成员和静态数据成员...
一般地,线程要读写类的私有成员变量,只有两种方法:将全局函数声明为类友元friend,或者使用静态的成员函数static。...本例就是自己的研究成果,使用非静态的成员函数作为线程函数,还能修改类的非静态的数据成员。
在没有讲述本章内容之前如果我们想要在一个范围内共享某一个数据,那么我们会设立全局对象,但面向对象的程序是由对象构成的,我们如何才能在类范围内共享数据呢? 这个问题便是本章的重点:
编写一个类,声明一个数据成员和一个静态数据成员:(1)让构造函数初始化数据成员,并把静态成员加1,让析构函数把静态成员...(3)添加一个静态成员函数,并用它来访问静态数据成员,再次,使静态数据成员为保护的。
静态成员函数和非静态成员函数的根本区别在于非静态函数由对象名.或者对象指针->调用,调用时编译器会向函数传递this指针;静态成员函数则有类名::或者对象名.调用,编译器不向函数传递this指针,不识别对象个体,...
编写一个类,声明一个数据成员和一个静态数据成员,让构造函数初始化数据成员,并把静态数据成员加1,让析构函数把静态成员减1。(创建三个对象,然后显示他们的数据成员和静态成员,在析构每个对象,显示结果。)
一个简单的比较,C++基础学习知识点,很容易理解,适合小白
完善Body类,将检测胖瘦的标准定义为静态数据成员并设计相应的静态成员函数。(最好给出main函数代码和运行结果) 定义Boat;和Car两个类,二者都有weight属性,定义二者的一个友元函数totalWeight(),计算二者...
学习友元函数的定义和原理。 •学习静态数据成员和静态成员函数的使用。 •学习静态成员代替全局变量实现对象间的共享。
静态成员函数只能访问静态数据成员、静态成员函数和类以外的函数和数据,不能访问非静态数据成员,但静态成员函数或静态数据成员可由任意访问许可的函数访问。原因是:当前对象的地址(this)是被隐含地传递到被调用...
1、讲解static静态局部变量的原理与特点; 2、讲解static静态全局变量的原理与特点; 3、讲解static静态成员变量的原理与特点; 4、讲解static静态成员函数的原理与特点;
C++静态成员函数小结.doc 类体中的数据成员的声明前加上static关键字,该数据成员就成为了该类的静态...和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点:
用于描述C语言中的数据中的静态函数.可以通过此概念的描述掌握静态数据的意义.
和其他数据成员一样,静态数据成员也遵守public/protected/private访问规则。同时,静态数据成员还具有以下特点: 1.静态数据成员的定义。 静态数据成员实际上是类域中的全局变量。所以,静态数据成员的定义(初始化)...
也不能在类的构造函数中初始化该成员,因为静态数据成员为类的各个对象共享,否则每次创建一个类的对象则静态数据成员都要被重新初始化。 静态成员不可在类体内进行赋值,因为它是被所有该类的对象所
声明字符型静态数据成员ServerName,保存其服务器名称;声明整型静态数据成员clientNum,记录已定义的客户数量;定义静态函数ChangeServerName()改变服务器名称。在头文件client.h中声明类,在文件client.cpp中实现...
和静态数据成员一样,静态成员函数是类的一部分,而不是对象的一部分。 如果要在类外调用公用的静态成员函数,要用类名和域运算符“::”。如 Box::volume( ); 实际上也允许通过对象名调用静态成员函数,如 a....