为什么类的静态成员函数在定义的时候不写static定义静态变量

博客访问: 413980
博文数量: 101
博客积分: 2812
博客等级: 少校
技术积分: 1542
注册时间:
APP发帖 享双倍积分
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
分类: C/C++
数据成员可以分静态变量、非静态变量两种.静态成员:静态类中的成员加入 static 修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员.非成静态员:所有没有加 Static 的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问..非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中..一个类中也可以包含静态成员和非静态成员,类中也包括静态构造函数和非静态构造函数..分两个方面来总结,第一方面主要是相对于面向过程而言,即在这方面不涉及到类,第二方面相对于面向对象而言,主要说明 static 在类中的作用。一、在面向过程设计中的 static 关键字1、静态全局变量定义:在全局变量前,加上关键字 static 该变量就被定义成为了一个静态全局变量。特点:& & & A、该变量在全局数据区分配内存。& & & B、初始化:如果不显式初始化,那么将被隐式初始化为 0(自动变量是随机的,除非显式地初始化)。& & & C、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。例(摘于 C++程序设计教程---钱能主编 P103) //file1.cpp& & & & & & & & & & & & & & &://Example 1#include void fn(); //定义静态全局变量void main(){& & & n=20;& & & cout < <n < <& & & fn();}void fn(){& & & n++;& & & cout < <n < <}& & & D、文件作用域下声明的 const 的常量默认为 static 存储类型。静态变量都在全局数据区分配内存, & & & & & & 包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:代码区全局数据区堆区栈区& & & 一般程序的由 new 产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。 & & & & & & 全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1 中的代码中将 //定义静态全局变量改为: //定义全局变量程序照样正常运行。的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:静态全局变量不能被其它文件所用;(好像是区别 extern 的)其它文件中可以定义相同名字的变量,不会发生冲突;您可以将上述示例代码改为如下://Example 2//File1#include void fn(); //定义静态全局变量(只能在本文件中使用)void main(){& & & n=20;& & & cout << n <<& & & fn();}//File2#include (可在别的文件中引用这个变量)void fn(){& & & n++;& & & cout < <n < <}编译并运行 Example 2,您就会发现上述代码可以分别通过编译,但 link 时出现错误。试着将 //定义静态全局变量改为 //定义全局变量再次编译运行程序,细心体会全局变量和静态全局变量的区别。2、静态局部变量 定义:在局部变量前加上 static 关键字时,就定义了静态局部变量。我们先举一个静态局部变量的例子,如下://Example 3#include void fn();void main(){& & & fn();& & & fn();& & & fn();}void fn(){& & & static n=10;& & & cout < <n < <& & & n++;}& & & 通常, & & 在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。& & & 但有时候我们需要在两次调用之间对变量的值进行保存。 & & 通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。& & & 静态局部变量正好可以解决这个问题。 & & 静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。特点:& & & A、该变量在全局数据区分配内存。& & & B、初始化:如果不显式初始化,那么将被隐式初始化为 0,以后的函数调用不再进行初始化。& & & C、它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或 语句块结束时,其作用域随之结束。& & & 3、静态函数(注意与类的静态成员函数区别) 定义:在函数的返回类型前加上 static关键字,函数即被定义成静态函数。特点:A.静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。 静态函数的例子://Example 4#include static void fn();//声明静态函数void main(){& & &fn();}void fn()//定义静态函数{& & &int n=10;& & &cout < <n < <}定义静态函数的好处:静态函数不能被其它文件所用;其它文件中可以定义相同名字的函数,不会发生冲突;二、面向对象的 static 关键字(类中的 static 关键字)1、静态数据成员在类内数据成员的声明前加上关键字 static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。//Example 5#include class Myclass{public:& & &Myclass(int a,int b,int c);& & &void GetSum();private:& & &int a,b,c;& & &static int S//声明静态数据成员};int Myclass::Sum=0;//定义并初始化静态数据成员Myclass::Myclass(int a,int b,int c){& & &this->a=a;& & &this->b=b;& & &this->c=c;& & &Sum+=a+b+c;}void Myclass::GetSum(){& & &cout < <"Sum=" < <Sum < <}void main(){& & &Myclass M(1,2,3);& & &M.GetSum();& & &Myclass N(4,5,6);& & &N.GetSum();& & &M.GetSum();}可以看出,静态数据成员有以下特点:&#61548; 对于非静态数据成员, & & & & & & 每个类对象都有自己的拷贝。 & & &而静态数据成员被当作是类的成员。& & &无论这个类的对象被定义了多少个, & & & & & & & &静态数据成员在程序中也只有一份拷贝, 由该类型& & &的所有对象共享访问。也就是说,静态数据成员是该类的所有对象所共有的。对该类的& & &多个对象来说,静态数据成员只分配一次内存,供所有对象共用。所以,静态数据成员& & &的值对每个对象都是一样的,它的值可以更新;&#61548; 静态数据成员存储在全局数据区。 & & & & & & & & & 静态数据成员定义时要分配空间, 所以不能在类声明& & &中定义。在 Example 5 中,语句 int Myclass::Sum=0;是定义静态数据成员;&#61548; 静态数据成员和普通数据成员一样遵从 public,protected,private 访问规则;&#61548; 因为静态数据成员在全局数据区分配内存,属于本类的所有对象共享,所以,它不属于& & &特定的类对象,在没有产生类对象时其作用域就可见,即在没有产生类的实例时,我们& & &就可以操作它;静态数据成员初始化与一般数据成员初始化不同。静态数据成员初始化的格式为:::=类的静态数据成员有两种访问形式:. 或 ::如果静态数据成员的访问权限允许的话(即 public 的成员) & & & & & & & ,可在程序中,按上述格式来引用静态数据成员 ;静态数据成员主要用在各个对象都有相同的某项属性的时候。 & & & & & & & & & &比如对于一个存款类,每个实例的利息都是相同的。 & & & & & & 所以, 应该把利息设为存款类的静态数据成员。 & & &这有两个好处,第一,不管定义多少个存款类对象, & & & & & & & 利息数据成员都共享分配在全局数据区的内存, & & 所以节省存储空间。 & &第二, & 一旦利息需要改变时, & & & & & 只要改变一次, 则所有存款类对象的利息全改变过来了;同全局变量相比,使用静态数据成员有两个优势:&#61548; 静态数据成员没有进入程序的全局名字空间, & & & & & & & & & 因此不存在与程序中其它全局名字冲突的& & &可能性;&#61548; 可以实现信息隐藏。静态数据成员可以是 private 成员,而全局变量不能;2、静态成员函数& & &与静态数据成员一样, & & & & & & & &我们也可以创建一个静态成员函数, 它为类的全部服务而不是为某一个类的具体对象服务。静态成员函数与静态数据成员一样,都是类的内部实现,属于类定义的一部分。普通的成员函数一般都隐含了一个 this 指针,this 指针指向类的对象本身,因为普通成员函数总是具体的属于某个类的具体对象的。通常情况下,this 是缺省的。如函数 fn()实际上是 this->fn()。但是与普通函数相比,静态成员函数由于不是与任何的对象相联系,因此它不具有 this 指针。从这个意义上讲,它无法访问属于类对象的非静态数据成员,也无法访问非静态成员函数, & & & & & & & & & &它只能调用其余的静态成员函数。下面举个静态成员函数的例子。//Example 6#include class Myclass{public:& & &Myclass(int a,int b,int c);& & &static void GetSum();/声明静态成员函数private:& & &int a,b,c;& & &static int S//声明静态数据成员};int Myclass::Sum=0;//定义并初始化静态数据成员Myclass::Myclass(int a,int b,int c){& & &this->a=a;& & &this->b=b;& & &this->c=c;& & &Sum+=a+b+c; //非静态成员函数可以访问静态数据成员}void Myclass::GetSum() //静态成员函数的实现{& & &// cout < )为一个类的对象或指向类对象的指& 针调用静态成员函数;
阅读(8640) | 评论(1) | 转发(1) |
相关热门文章
给主人留下些什么吧!~~
全局变量用着挺方便的
请登录后评论。1861人阅读
c/c++ learning(32)
& & & & C中的static使用比较简单,都不陌生了,C&#43;&#43;中static关键字在类中的使用需要注意一些细节。static在类中修饰的是数据成员以及成员函数,分别称之为静态数据成员及静态成员函数。
& & & & 先来看看static静态数据成员的目的及使用:
& & & & (1) 对于特定类型的全体对象而言,有时候可能需要访问一个全局的变量。比如说统计某种类型对象已创建的数量。
& & & & (2) 如果我们用全局变量会破坏数据的封装,一般的用户代码都可以修改这个全局变量。这时我们可以用类的静态成员来解决这个问题。
& & & & (3) 非静态数据成员存在于类类型的每个对象中,静态数据成员则独立于该类的任意对象而存在,它是与类关联的对象,不与类对象关联。
& & & & static静态数据成员的优点:
& & & & (1) static静态数据成员的名字是在类的作用域中,因此可以避免与其它类成员或全局对象名字冲突。
& & & & (2) 可以实施封装,static静态数据成员可以是私有的,而全局对象则不可以。
& & & & (3) 阅读程序容易看出static成员与某个类相关联,这种可见性可以清晰地反映程序员的意图。
& & & & static成员函数需要注意的事项:
& & & & (1) static成员函数没有this指针,因为它是与类关联的,不与对象关联
& & & & (2) 非静态成员函数可以访问静态成员
& & & & (3) 静态成员函数不可以访问非静态成员。
& & & & 下面举几个例子来说明静态数据成员及静态成员函数的使用方法。
& & & & &先来看看下面的统计对象个数的类的定义。
& & & & CountedObject.h
_COUNTED_OBJECT_H
#define _COUNTED_OBJECT_H
class CountedObject
CountedObject();
~CountedObject();
static int GetCount(); //静态成员函数
static int count_; // 静态成员函数在定义时有两步:1 静态成员的引用性声明 2 在文件域上进行定义性说明。 这里只是第一步
& & & & 统计对象类的实现, CountedObject.cpp & & &&
#include &CountedObject.h&
int CountedObject::count_ = 100; //静态成员函数定义性声明方法:1 需要加上类名域运算符 2不需要static关键字 3 只能在文件作用域中进行初始化,不能在类中进行初始化
CountedObject::CountedObject()
++count_; //创建对象时自加
CountedObject::~CountedObject()
--count_; 销毁对象时自减
//静态成员函数在定义时不加static修饰,只能访问静态数据成员,不能访问普通数据成员
int CountedObject::GetCount()
return count_;
& & & 下面是对静态数据成员及静态成员函数的访问例子
& & & &Test1.cpp
#include &CountedObject.h&
#include &iostream&
int main()
//cout && CountedObject::count_ && //静态数据成员可以用类名来访问,如果是私有的则不能访问了,只能提供一个公有接口来访问
cout && CountedObject::GetCount() &&
//output:100
CountedObject co1;
cout && CountedObject::GetCount() && //output:101
CountedObject *co2 = new CountedO
cout && CountedObject::GetCount() && //output:102
delete co2;
cout && CountedObject::GetCount() && //output:101
& & & & 静态常量数据成员
& & & & 首先,静态常量数据成员它属于静态的数据成员,与静态数据成员不同的是,它的&#20540;是const,不能被修改。并且静态常量数据成员也是与类关联的,全体所有对象共享。普通成员函数及静态成员函数均可以访问它。
#include &iostream&
class Test
//static const int x_;
//1 与static int x_;不同的是,它的初始化可以在类体中进行
//2 但是也只有static const int, static const char(静态常量整型数据成员)才可以在类体中初始化,如double则不行.
//3 但是静态常量整型数据成员在类体中初始化方法在VC6.0则是行不通的,VC6.0编译器比较古老,不支持。
//所以个人还是觉得统一一下,在类体外初始化比较好。
static const int x_ = 100; //静态常量数据成员
//const int Test::x_ = 100;
const int Test::x_;
int main(void)
cout && t.x_ && //output:100
cout && Test::x_ && //output:100
//Test::x_ = Test::x_ + 1; //Error,不能给常量赋值
//t.x_ = t.x_ + 1; //同上
& & & & 下面的例子是关于普通成员函数可以访问静态数据成员及静态成员函数,而静态成员函数只能访问静态数据成员,而不能访问普通数据成员的例子(原因是静态成员函数没有this指针)
#include &iostream&
class Test
Test(int y):y_(y)
void TestFun()
cout && &x=&&& x_ && //非静态成员函数访问静态数据成员
TestStaticFun(); //非静态成员函数访问静态成员函数
static void TestStaticFun()
//TestFun(); //Error,静态成员函数不能访问非静态成员函数
//cout && &y = &&& y_ && //Error,静态成员函数不能访问非静态成员,因为静态成员函数没有隐含的this指针,故无法指向普通对象的非静态成员。而且也不能访问非静态成员函数,因为非静态成员与非静态成员函数是属于对象的,而静态成员与静态成员函数是属于类的,但是对象可以访问类的静态成员与静态成员函数
cout && &TestStaticFun()..x=&&&x_&&
static int x_; //静态成员的引用性声明
int Test::x_ = 100; //静态数据成员的定义性说明。
int main()
Test t(10);
t.TestFun();
cout && t.x_ && //对象可以访问静态成员。这是允许的,但是不推荐,让人误解以为x_是属于t对象的。
cout && Test::x_ &&//推荐这么访问
& & & & 关于类/对象大小的计算
& & & & (1) 首先,类大小的计算遵循结构体的对齐原则
& & & & (2) 类的大小与普通数据成员有关,与成员函数无关,即普通成员函数,静态成员函数,静态数据成员,静态常量数据成员均对类的大小无影响
& & & & (3) 虚函数对类的大小有影响(后面再说明),主要是虚表指针带来的影响
& & & & (4) 虚继承对类的大小有影响(后面再说明),主要是虚基表指针带来的影响
& & & & 按照上面的类大小计算原则,对前面一个例子的Test类大小可以进行计算,由于它只有一个普通数据成员y_,静态数据成员与静态成员函数,普通成员函数均对类大小无影响,所以前一个例子的类大小为:4bytes,如果不信可以用sizeof(Test)进行计算测试。^_^
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:342816次
积分:2987
积分:2987
排名:第9240名
原创:65篇
转载:24篇
评论:92条
(1)(2)(2)(15)(1)(2)(3)(2)(3)(6)(5)(2)(2)(1)(5)(1)(1)(2)(5)(1)(1)(10)(2)(11)(3)静态成员变量和静态成员函数(static) - ~Shadow - 博客园
随笔 - 8, 文章 - 0, 评论 - 0, 引用 - 0
数据成员可以分静态变量、非静态变量两种.
静态成员:静态类中的成员加入static修饰符,即是静态成员.可以直接使用类名+静态成员名访问此静态成员,因为静态成员存在于内存,非静态成员需要实例化才会分配内存,所以静态成员不能访问非静态的成员..因为静态成员存在于内存,所以非静态成员可以直接访问类中静态的成员.
非成静态员:所有没有加Static的成员都是非静态成员,当类被实例化之后,可以通过实例化的类名进行访问..非静态成员的生存期决定于该类的生存期..而静态成员则不存在生存期的概念,因为静态成员始终驻留在内容中..
一个类中也可以包含静态成员和非静态成员,类中也包括静态构造函数和非静态构造函数..
分两个方面来总结,第一方面主要是相对于面向过程而言,即在这方面不涉及到类,第二方面相对于面向对象而言,主要说明static在类中的作用。
一、在面向过程设计中的static关键字
1、静态全局变量
定义:在全局变量前,加上关键字 static 该变量就被定义成为了一个静态全局变量。
  A、该变量在全局数据区分配内存。
  B、初始化:如果不显式初始化,那么将被隐式初始化为0(自动变量是随机的,除非显式地初始化)。
  C、访变量只在本源文件可见,严格的讲应该为定义之处开始到本文件结束。
  例(摘于C++程序设计教程---钱能主编P103):         //file1.cpp
        //Example 1
&&&&&&&&&&&&&&&&&&&&&&&&&&& #include &iostream.h&
&&&&&&&&&&&&&&&&&&&&&&&&&&& void fn();
&&&&&&&&&&&&&&&&&&&&&&&&&&&& //定义静态全局变量
&&&&&&&&&&&&&&&&&&&&&&&&&&&& void main()
&&&&&&&&&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&& n=20;
&&&&&&&&&&&&&&& cout&&n&&
&&&&&&&&&&&&&&& fn();
&&&&&&&&&&&&&&&&&&&&&&&&&&&& }
&&&&&&&&&&&&&&&&&&&&&&&&&&&&& void fn()
&&&&&&&&&&&&&&&&&&&&&&&&&&&&& {
&&&&&&&&&&&&&&& n++;
&&&&&&&&&&&&&&& cout&&n&&
&&&&&&&&&&&&&&&&&&&&&&&&&&&&& }
  D、文件作用域下声明的const的常量默认为static存储类型。
静态变量都在全局数据区分配内存,包括后面将要提到的静态局部变量。对于一个完整的程序,在内存中的分布情况如下图:
  代码区全局数据区堆区栈区
  一般程序的由new产生的动态数据存放在堆区,函数内部的自动变量存放在栈区。自动变量一般会随着函数的退出而释放空间,静态数据(即使是函数内部的静态局部变量)也存放在全局数据区。全局数据区的数据并不会因为函数的退出而释放空间。细心的读者可能会发现,Example 1中的代码中将
&&&&&&&&&&&&&&&& //定义静态全局变量
//定义全局变量
程序照样正常运行。的确,定义全局变量就可以实现变量在文件中的共享,但定义静态全局变量还有以下好处:
静态全局变量不能被其它文件所用;(好像是区别extern的) 其它文件中可以定义相同名字的变量,不会发生冲突; 您可以将上述示例代码改为如下: //Example 2//File1#include &iostream.h&void fn(); //定义静态全局变量(只能在本文件中使用)void main(){ n=20; cout&&n&& fn();}//File2#include &iostream.h&(可在别的文件中引用这个变量)void fn(){ n++; cout&&n&&}
编译并运行Example 2,您就会发现上述代码可以分别通过编译,但link时出现错误。试着将 //定义静态全局变量
改为 //定义全局变量
再次编译运行程序,细心体会全局变量和静态全局变量的区别。
2、静态局部变量
定义:在局部变量前加上static关键字时,就定义了静态局部变量。
我们先举一个静态局部变量的例子,如下:
//Example 3#include &iostream.h&void fn();void main(){ fn(); fn(); fn();}void fn(){ static n=10; cout&&n&& n++;}
  通常,在函数体内定义了一个变量,每当程序运行到该语句时都会给该局部变量分配栈内存。但随着程序退出函数体,系统就会收回栈内存,局部变量也相应失效。
  但有时候我们需要在两次调用之间对变量的值进行保存。通常的想法是定义一个全局变量来实现。但这样一来,变量已经不再属于函数本身了,不再仅受函数的控制,给程序的维护带来不便。
  静态局部变量正好可以解决这个问题。静态局部变量保存在全局数据区,而不是保存在栈中,每次的值保持到下一次调用,直到下次赋新值。
  A、该变量在全局数据区分配内存。
  B、初始化:如果不显式初始化,那么将被隐式初始化为0,以后的函数调用不再进行初始化。
  C、它始终驻留在全局数据区,直到程序运行结束。但其作用域为局部作用域,当定义它的函数或 语句块结束时,其作用域随之结束。
3、静态函数(注意与类的静态成员函数区别)
定义:在函数的返回类型前加上static关键字,函数即被定义成静态函数。
  A、静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。
静态函数的例子:
//Example 4#include &iostream.h&static void fn();//声明静态函数void main(){ fn();}void fn()//定义静态函数{ int n=10; cout&&n&&}
定义静态函数的好处:
静态函数不能被其它文件所用; 其它文件中可以定义相同名字的函数,不会发生冲突; 二、面向对象的static关键字(类中的static关键字) 1、静态数据成员
在类内数据成员的声明前加上关键字static,该数据成员就是类内的静态数据成员。先举一个静态数据成员的例子。
//Example 5
#include &iostream.h&
class Myclass{
public: Myclass(int a,int b,int c);
void GetSum();
private: int a,b,c;
static int S//声明静态数据成员
int Myclass::Sum=0;//定义并初始化静态数据成员
Myclass::Myclass(int a,int b,int c)
this-&a=a;
this-&b=b;
this-&c=c;
Sum+=a+b+c;
void Myclass::GetSum(){
cout&&"SSum="&&Sum&&
void main()
Myclass M(1,2,3);
M.GetSum();
Myclass N(4,5,6);
N.GetSum();
Myclass::GetSum();
关于静态成员函数,可以总结为以下几点:
出现在类体外的函数定义不能指定关键字static; 静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数; 非静态成员函数可以任意地访问静态成员函数和静态数据成员; 静态成员函数不能访问非静态成员函数和非静态数据成员; 由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长; 调用静态成员函数,可以用成员访问操作符(.)和(-&)为一个类的对象或指向类对象的指针调用静态成员函数,也可以直接使用如下格式: <类名>::<静态成员函数名>(<参数表>)
调用类的静态成员函数。C/C++(36)
C语言中static函数的作用:
C程序一直由下列部分组成:
&&&&&&1)正文段——CPU执行的机器指令部分;一个程序只有一个副本;只读,防止程序由于意外事故而修改自身指令;&&&&
&&2)初始化数据段(数据段)——在程序中所有赋了初&#20540;的全局变量,存放在这里。&&&&
&&3)非初始化数据段(bss段)——在程序中没有初始化的全局变量;内核将此段初始化为0。&&&&&
&&4)栈——增长方向:自顶向下增长;自动变量以及每次函数调用时所需要保存的信息(返回地址;环境信息)。&&&&&&
&&5)堆——动态存储分。
在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。
&&&1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)
&&2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的&#20540;是任意的,除非他被显示初始化)
&&&3)作用域:全局静态变量在声明他的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。
定义全局静态变量的好处:
&1&不会被其他文件所访问,修改
&2&其他文件中可以使用相同名字的变量,不会发生冲突。
局部静态变量
在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。
&&1)内存中的位置:静态存储区
&&2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的&#20540;是任意的,除非他被显示初始化)
&&3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。
&注:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对他进行访问。
当static用来修饰全局变量的时候,它就改变了全局变量的作用域(在声明他的文件之外是不可见的),但是没有改变它的存放位置,还是在静态存储区中。
3.&静态函数
&在函数的返回类型前加上关键字static,函数就被定义成为静态函数。
&&函数的定义和声明默认情况下是extern的,但静态函数只是在声明他的文件当中可见,不能被其他文件所用。
定义静态函数的好处:
&1&&其他文件中可以定义相同名字的函数,不会发生冲突
&2&&静态函数不能被其他文件所用。&存储说明符auto,register,extern,static,对应两种存储期:自动存储期和静态存储期。&auto和register对应自动存储期。具有自动存储期的变量在进入声明该变量的程序块时被建立,它在该程序块活动时存在,退出该程序块时撤销。
关键字extern和static用来说明具有静态存储期的变量和函数。用static声明的局部变量具有静态存储持续期(static&storage&duration),或静态范围(static&extent)。虽然他的&#20540;在函数调用之间保持有效,但是其名字的可视性仍限制在其局部域内。静态局部对象在程序执行到该对象的声明处时被首次初始化。
由于static变量的以上特性,可实现一些特定功能。
1.&统计次数功能
声明函数的一个局部变量,并设为static类型,作为一个计数器,这样函数每次被调用的时候就可以进行计数。这是统计函数被调用次数的最好的办法,因为这个变量是和函数息息相关的,而函数可能在多个不同的地方被调用,所以从调用者的角度来统计比较困难。
C&#43;&#43;类静态成员与类静态成员函数
& 当将类的某个数据成员声明为static时,该静态数据成员只能被定义一次,而且要被同类的所有对象共享。各个对象都拥有类中每一个普通数据成员的副本,但静态数据成员只有一个实例存在,与定义了多少类对象无关。静态方法就是与该类相关的,是类的一种行为,而不是与该类的实例对象相关。
& & 静态数据成员的用途之一是统计有多少个对象实际存在。
& & 静态数据成员不能在类中初始化,实际上类定义只是在描述对象的蓝图,在其中指定初&#20540;是不允许的。也不能在类的构造函数中初始化该成员,因为静态数据成员为类的各个对象共享,否则每次创建一个类的对象则静态数据成员都要被重新初始化。
& & 静态成员不可在类体内进行赋&#20540;,因为它是被所有该类的对象所共享的。你在一个对象里给它赋&#20540;,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋&#20540;。
& & 静态成员的&#20540;对所有的对象是一样的。静态成员可以被初始化,但只能在类体外进行初始化。
& & 一般形式:
& & 数据类型类名::静态数据成员名=初&#20540;
& & 注意:不能用参数初始化表对静态成员初始化。一般系统缺省初始为0。
1、static成员的所有者是类本身和对象,但是多个对象拥有一样的静态成员。从而在定义对象是不能通过构造函数对其进行初始化。
2、静态成员不能在类定义里边初始化,只能在class body外初始化。
3、静态成员仍然遵循public,private,protected访问准则。
4、静态成员函数没有this指针,它不能调用非静态成员,因为除了对象会调用它外,类本身也可以调用。
静态成员函数可以直接访问该类的静态数据和静态函数成员,而访问非静态数据成员必须通过参数传递的方式得到一个对象名,然后通过对象名来访问。
非静态成员函数可以任意地访问静态成员函数和静态数据成员。静态成员函数不能访问非静态成员函数和非静态数据成员。
关于静态成员函数,可以总结为以下几点:
出现在类体外的函数定义不能指定关键字static;
静态成员之间可以相互访问,包括静态成员函数访问静态数据成员和访问静态成员函数;
非静态成员函数可以任意地访问静态成员函数和静态数据成员;
静态成员函数不能访问非静态成员函数和非静态数据成员;
由于没有this指针的额外开销,因此静态成员函数与类的全局函数相比速度上会有少许的增长;
调用静态成员函数,可以用成员访问操作符(.)和(-&)为一个类的对象或指向类对象的指针调用静态成员函数,
当同一类的所有对象使用一个量时,对于这个共用的量,可以用静态数据成员变量,这个变量对于同一类的所有的对象都取相同的&#20540;。静态成员变量只能被静态成员函数调用。静态成员函数也是由同一类中的所有对象共用。只能调用静态成员变量和静态成员函数。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:71210次
积分:1657
积分:1657
排名:第19383名
原创:62篇
转载:244篇
(4)(11)(27)(16)(21)(24)(19)(20)(19)(34)(8)(24)(27)(21)(24)(5)(1)(3)(2)(3)}

我要回帖

更多关于 静态数据成员的定义 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信