Static是C++中一个常见的关键字,它被用来控制变量的存储方式和可见性。

在类定义中,它的成员(包括数据成员和成员函数)可以用关键字static申明为静态成员。静态成员的特性是不管这个类创建了多少个对象,它其中的静态成员只有一个拷贝,这个拷贝被所有属于这个类的对象共享。

从原理来分析,我们能清楚的了解,类的数据成员和成员函数都是跟着类的执行,在编译器上为他在堆栈上分配内存空间存储的。静态数据成员和静态成员函数和他们不同,它们是在程序开始运行时候存储在静态存储空间的。

  • 静态数据成员

在一个类中,如果将一个数据成员申明为static,这种成员就被称为静态数据成员。与一般数据成员不同的是,无论建立多少个类的对象,都只有一个静态数据成员拷贝。

首先,我们通过一个例子来分析一下静态数据成员。

 #include "stdafx.h"
#include "stdlib.h" class Student{
static int count; // 申明静态数据成员,统计学生总数
int studentNo; // 普通数据成员,表示学生学号 public:
Student()
{
count++; // 每创建一个对象,学生个数加1
studentNo = count; // 给当前学生学号赋值
} void print()
{
printf("Student%d", studentNo);
printf("count = %d\n", count);
}
};
int Student::count = ; // 初始化静态数据成员count int _tmain(int argc, _TCHAR* argv[])
{
Student Student1; // 创建第一个学生对象
Student1.print();
printf("----------------\n"); Student Student2; // 创建第二个学生对象
Student1.print();
Student2.print();
printf("----------------\n"); Student Student3; // 创建第三个学生对象
Student1.print();
Student2.print();
Student3.print(); system("pause");
return ;
}

上述程序的运行结果如下:

从运行结果可以看出,所有对象的count值都是相同的,这个说明他们都共享这个数据,也就是说明所有对象对于count只有一个拷贝,这就是静态数据成员的特性(作用和全局变量类似)。普通数据成员studentNo各个对象的值是不同的,所以它存放的是各个对象的对象号。

说明:

  1. 静态数据成员属于类,而不像普通的数据成员那样属于某个对象,因此我们可以用“类名::”这样的形式访问静态数据成员。如:Student::count。
  2. 静态数据成员不能在类中进行初始化,因为类中不给他分配内存空间(前面说的类中存储地址是堆栈,静态数据成员存储地址是静态存储空间),所以必须在其他地方为他提供定义和初始化。默认时,静态成员被初始化为0。
  3. 静态数据成员和静态变量一样,是在编译时创建并进行初始化的。它在该类的任何对象创建之前就已经存在。因此,公有的静态数据成员可以在对象定义之前就被访问。对象定以后,公有的静态数据成员也可以通过对象进行访问,格式如下:

    对象名.静态数据成员名;

    对象名->静态数据成员名;

  4. 静态数据成员也遵循public,protect,private的原则。所以,私有的静态数据成员不能被类外部函数访问,也不能用对象进行访问。
  5. 静态数据成员的类型可以是该成员所属的类类型。非静态数据成员被限定为申明其自身类的对象的指针或引用。
 class A{
private:
static A a1; // OK
A *a1; // OK
A a3; // Error
};

   6. 静态数据成员可以用作默认实参,而普通数据成员不可以。  

 class Example{
public:
static int a;
int b; void fun1(int i = a); // 正确,a为静态数据成员
void fun2(int i = b); // 错误,b为普通数据成员
};

   7. C++支持静态数据成员的一个主要原因是可以不必使用全局变量。依赖于全局变量的类很容易违反面向对象程序的封装原理。静态数据成员的主要用途是定义类的各个对象所公用的数据,如:统计数据、平均数等。

  • 静态成员函数

在类定义中,在成员函数之前加上static申明成为静态成员函数。和静态数据成员一样,静态成员函数属于整个类,是该类的所有对象共享的成员函数,而不是属于某个对象特有的函数。定义静态成员函数的格式如下:

Static 返回类型 函数名(实参表)

与静态数据成员一样,它也遵循public,protect和private的原则。调用公有的静态成员函数格式如下:

类名::静态成员函数(实参表)

对象名.静态成员函数(实参表)

对象名->静态成员函数(实参表)

下面我们通过一个例子来了解静态成员函数。

 #include "stdafx.h"
#include "stdlib.h" class small_cat{
private:
int weight;
static int total_weight;
static int totel_num;
public:
small_cat(int w)
{
weight = w;
total_weight += w;
totel_num++;
} void display()
{
printf("The small cat weight %d pounds\n", weight);
} static void total_disp()
{
printf("%d small cat weight ", totel_num);
printf(" %d pounds\n", total_weight);
}
};
int small_cat::total_weight = ;
int small_cat::totel_num = ; int _tmain(int argc, _TCHAR* argv[])
{
small_cat w1(),w2(),w3();
w1.display();
w2.display();
w3.display(); small_cat::total_disp(); system("pause");
return ;
}

程序运行结果:

说明:

  1. 静态成员函数可以定义成内嵌的,也可以在内外定义,在类外定义是,前面不需要加static。
  2. 一般情况下,静态成员函数主要是用来访问全局变量或者同一个类中的静态数据成员。
  3. 私有静态成员函数不能被类的外部函数和对象访问。
  4. 使用静态成员函数的一个原因就是可以用它在建立任何对象之前处理静态数据成员这是普通成员函数不能实现的。
  5. 编译系统将静态成员函数限定为内部连接,也就是说,与现行的文件相连接的文件中的同名函数不会与该函数发生冲突,维护了该函数的安全性,这是使用静态成员函数的另外一个原因。
  6. 在一般的成员函数中都隐藏一个this指针,用来指向对象自身,而在静态成员函数中没有这个this指针,因为它不与特定的对象相关联。调用静态成员函数使用如下格式:类名::静态成员函数名();
  7. 静态成员函数不能被申明为const,因为static成员不是任何对象的组成部分,毕竟,将成员函数申明为const就是承诺不会修改该函数所属的对象。
  8. 静态成员函数不能被申明为虚函数。
  9. 一般而言,静态成员函数不可访问类中的非静态成员。如果确实需要,静态成员函数只能通过对象名(或指向对象名的指针)访问该对象的非静态成员。如:
 static void display(small_cat &w)
{
printf("The small cat weight %d pounds\n", w.weight);
}
  • 延伸

静态局部变量

静态局部变量属于静态存储方式,它具有以下特点:

(1)静态局部变量在函数内定义,但不像自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序。

(2)静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。

(3)允许对构造类静态局部量赋初值。若未赋以初值,则由系统自动赋值。数值型变量自动赋初值0,字符型变量赋空字符。

(4)对基本类型的静态局部变量若在说明时未赋以初值,则系统自动赋予0值。而对自动变量不赋初值,则其值是不定的。 根据静态局部变量的特点,可以看出它是一种生存期为整个源文件的量。虽然离开定义它的函数后不能使用,但如再次调用定义它的函数时,它又可继续使用, 而且保存了前次被调用后留下的值。 因此,当多次调用一个函数且要求在调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。

C++ Static(静态成员)的作用总结的更多相关文章

  1. 关键字static/const的作用

    static关键字的作用:(1)设置变量的存储域,函数体内static变量的作用范围为该函数体,不同于auto变量,该变量的内存只被分配一次,因此其值在下次调用时仍维持上次的值:(2)限制变量的作用域 ...

  2. C++ 类的static静态成员

    静态static 静态成员的提出是为了解决数据共享的问题.实现共享有许多方法,如:设置全局性的变量或对象是一种方法.但是,全局变量或对象是有局限性的. 在全局变量前,加上关键字static该变量就被定 ...

  3. java基础(五)之static关键词的作用

    static关键词的作用 1.静态成员变量的语法特定2.静态函数的语法特定3.静态代码块的语法特定 定义静态成员变量 Person.java class Person{ static int a; } ...

  4. 想用@Autowired注入static静态成员?官方不推荐你却还偏要这么做

    生命太短暂,不要去做一些根本没有人想要的东西.本文已被 https://www.yourbatman.cn 收录,里面一并有Spring技术栈.MyBatis.JVM.中间件等小而美的专栏供以免费学习 ...

  5. 缓存篇(Cache)~第一回 使用static静态成员实现服务器端缓存(导航面包屑)

    返回目录 今天写缓存篇的第一篇文章,在写完目录后,得到了一些朋友的关注,这给我之后的写作带来了无穷的力量,在这里,感谢那几位伙伴,哈哈! 书归正传,今天我带来一个Static静态成员的缓存,其实它也不 ...

  6. C++学习10 static静态成员变量和静态成员函数

    一般情况下,如果有N个同类的对象,那么每一个对象都分别有自己的成员变量,不同对象的成员变量各自有值,互不相干.但是有时我们希望有某一个或几个成员变量为所有对象共有,这样可以实现数据共享. 可以使用全局 ...

  7. C#: static关键字的作用(转)

    C#: static关键字的作用   static意思是静态,可以修饰类.字段.属性.方法 标记为static的就不用创建实例对象调用了,可以通过类名直接点出来 static三种用法: 1.用于变量前 ...

  8. c++学习笔记之类和对象(三、static静态成员变量和静态成员函数)

    一.static静态成员变量 对象的内存中包含了成员变量,不同的对象占用不同的内存,这使得不同对象的成员变量相互独立,它们的值不受其他对象的影响.是有时候我们希望在多个对象之间共享数据,对象 a 改变 ...

  9. 关于static/const的作用

    这个简单的问题很少有人能回答完全.在C语言中,关键字static有三个明显的作用: 1)在函数体内,一个被声明为静态的变量在这一函数被调用过程中维持其值不变(该变量存放在静态变量区). 2) 在模块内 ...

  10. c++,static 静态成员变量 / 静态成员函数

    静态成员变量: //静态成员变量(static) // //1.如果想在同类的多个对象之间实现数据共享 ,可以用静态 //成员变量,即用static修饰的成员变量,例 static int a; // ...

随机推荐

  1. WIN8 下Cisco VPN连接 出现vpn 422 failed to enable virtual adapter错误

    今天在家用VPN软件连接,出现了“vpn 422 failed to enable virtual adapter”的错误,系统安装的是Win8专业版32位,百度了半天又很多方法解决不了,后来发现了一 ...

  2. C++ Low level performance optimize 2

    C++ Low level performance optimize 2 上一篇 文章讨论了一些底层代码的优化技巧,本文继续讨论一些相关的内容. 首先,上一篇文章讨论cache missing的重要性 ...

  3. ubuntu 添加管理员账户

    sudo adduser cat 输入密码即可 sudo adduser cat sudo 为cat 添加sudo 权限

  4. iOS开发之企业发布无线安装APP

    前提是注册成为企业开发者(¥299),申请到证书并安装到本地,可以正常使用Xcode在IOS移动设备上进行Debug. 首先build看是否报错.如无错 执行下一: 执行Product—Archive ...

  5. RGB和HSB的转换推算

    RGB三原色是基于人肉眼对光线的生理作用.人眼内有三种椎状体“对这三种光线频率所能感受的带宽最大,也能独立刺激这三种颜色的受光体”,因此RGB称为三原色.比如,黄色波长的光对人眼的刺激效果,和红色与绿 ...

  6. 【MVC 过滤器的应用】ASP.NET MVC 如何统计 Action 方法的执行时间

    代码如下: using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; u ...

  7. (转) IPv6相关RFC

    转自http://blog.csdn.net/lucien_cc/article/details/12688477 IPv6 Spec RFC 2460 : Internet Protocol, Ve ...

  8. css的两种引用方式 link和@import

    学习web开发的最大乐趣就是不断的发现自己以前不曾见过的东西,这些东西对于我来说是那么的新鲜有趣. 比如说今天偶尔研究别人的网站,就发现了有趣的东东. 当点开此网页的css时(这个css文件命名方式就 ...

  9. publishing failed with multiple errors

    背景: 1.使用maven package工程 2. 在eclipse中添加server运行时 publishing failed with multiple errors resource is o ...

  10. HMM 自学教程(八)总结

    本系列文章摘自 52nlp(我爱自然语言处理: http://www.52nlp.cn/),原文链接在HMM 学习最佳范例,这是针对国外网站上一个 HMM 教程的翻译,作者功底很深,翻译得很精彩,且在 ...