转载自:https://blog.csdn.net/computer_liuyun/article/details/29235111

c++中的static静态数据成员和静态成员函数应该是让大家比较头疼的东西,好像也是找工作公司面试中常常问到的东西。我自己也深有体会,在学习c++的过程中,总感觉static很烦人,但是又是一个必须懂的东西,所以今天就对静态数据成员和静态成员函数坐下小结哈!

一、静态数据成员

1.静态数据成员怎么去定义?

在类中声明静态数据成员很简单,是以static关键字表明即可,如下所示

class Test{
private://静态数据成员static int a;
};

a就是静态数据成员了,在类中只能声明可是不能定义哈!

要对静态数据成员定义和初始化必须在类的外面也就是在全局作用域中定义,如果定义不给出初值,则默认初值为0

class Test{
public:int GetA() const{return a;}
private://静态数据成员static int a;
};
//int Test::a;如果这样定义不赋予初值则初值为零
int Test::a = 1;
#include <iostream>
int main()
{Test T;std::cout << T.GetA() << std::endl;
}

定义时一定要在全局作用域中定义,一定不要在类中定义!

静态数据成员甚至在类没有任何对象的时候都可以访问,静态成员可以独立访问,无需依赖任何对象的建立

另外,不要试图在头文件中定义(初始化)静态数据成员。在大多数的情况下,这样做会引起重复定义这样的错误。即使加上#ifndef #define #endif或者#pragma once也不行。

2.静态数据成员被类的所有对象共享,包括该类的派生类对象,基类对象和派生类对象共享基类的静态数据成员

答:静态数据成员不属于任何对象,类的静态数据成员的存在不依赖于任何类对象的存在,静态数据成员是由类的所有对象共享的。例子如下:

class Base{
public://静态数据成员static int a;
};
class Derived : public Base{};
//int Test::a;如果这样定义不赋予初值则初值为零
int Base::a;
#include <iostream>
int main()
{Base B;Derived D;B.a++;std::cout << B.a << std::endl;D.a++;std::cout << D.a << std::endl;}

打印结果如下:

由打印结果看出来,派生类对象和基类对象都是共享基类的静态数据成员,而基类的所有对象也是共享该静态数据成员,且该静态数据成员应该在全局作用域中定义,可以赋予初值也可以不赋予初值,如果不赋予初值,静态数据成员有其默认值。

3.静态数据成员可以作为成员函数的默认形参,而普通数据成员则不可以

答:不多说,直接看例子马上就明白了哈!

class Test{
public://静态数据成员static int a;int b;void fun_1(int i = a);//正确void fun_2(int i = b);//报错
};

4.静态数据成员的类型可以是所属类的类型,而普通数据成员则不可以。普通数据成员的只能声明为 所属类类型的 指针或引用

答:这个也不多说,直接看例子就可以懂什么意思哈!

class Test{
public://静态数据成员static Test a;//正确Test b;//报错Test *pTest;//正确Test &m_Test;//正确static Test *pStaticObject;//正确
};

5.静态数据成员在const函数中可以修改,而普通的数据成员是万万不能修改的哈!

答:看个例子

class Test{
public:Test():b(0){}//静态数据成员static int a;//正确int b;void test() const{a++;b++;//const指的不能修改当前调用该函数对象的数据成员}
};
int Test::a;

const修饰的时当前this指针所指向的对象是const,但是静态数据成员不属于任何类的对象,它被类的所有对象修改,所以this指针不修饰静态的数据成员,所以可以更改。

二、静态成员函数

静态成员函数的声明也很简单,就是在类的成员函数前加上static关键字即可,和静态成员一样,静态成员函数也是属于类的,它并不属于任何对象,当调用静态成员函数时应该使用类名和域运算符“∷”,当然也可以使用对象调用操作,但是这样的操作并不意味着静态成员函数属于这个对象,它只是被这个对象共享而已,这样也就决定了静态成员函数中是不能访问本类中的非静态数据成员的,它是不能访问非静态数据成员的,在c++中静态成员函数主要用来访问静态数据成员而不访问非静态数据成员

1.静态成员函数不能调用非静态成员函数,但是反过来是可以的

2.静态成员函数没有this指针,也就是说静态成员函数不能使用修饰符(也就是函数后面的const关键字)

3.静态成员函数的地址可用普通函数指针储存,而普通成员函数地址需要用 类成员函数指针来储存。

总结:其实声明为静态,不论是静态数据成员还是静态成员函数,它们都是不依赖于对象而存在的,类在定义后并不分配存储空间,而是在定义类的对象的时候才分配存储空间,相反静态的数据成员和静态的成员函数是已经在内存中开辟了内存空间了,所以静态数据成员可以独立的访问在任何类对象没有建立起来都可以访问,并且静态成员函数不可以调用非静态成员函数,因为非静态成员函数只有在类对象建立以后才可以调用,相反则是可以的。我觉得当对某个判断产生怀疑的时候应该去测试,只有验证了才知道是不是对的哈!

为了能更好阐释静态数据成员和静态成员函数,然后在网上搜了博客,感觉有些例子不错(因找不到最初的出处,所以无法注明请原作者谅解),所以就拿来给大家参考一下哈!

关于玩篮球的例子很能明显解释静态数据成员和静态成员函数到底是怎么回事

你们班里面有10个人(10个比如高一一班的对象),体育老师分给你们一个篮球(静态成员函数),你们每个人都带了一个篮球(非静态成员数),你们都很小气,自己的球只能自己拍,要是5对5打比赛,那就只能用那个静态的篮球了(每个人都可以拿来用,但是带来的影响是对全体的)。因此,我可以说那个篮球是高一一班的成员。所以也就是说:静态成员函数是类的成员函数(因为高一二班就不能拿来玩),但是这个篮球最后还是要还给老师的,任何私人不得占有。希望这样你能明白,其实在内存空间里面说白了静态的成员的内存是唯一的一份,就是当你在类外声明他时开辟的,但是非静态函数的空间分配是在你实例化对象时创建的。

为了使大家更好的理解这两个概念,还是老样子用代码来说明上面文字说明的这一切哈!

关于学生类的例子

//定义Student类
#include <iostream>
class Student
{
public:
//定义构造函数
Student(int n,int a,float s):num(n),age(a),score(s){ }
void total();
//声明静态成员函数
static float average();
private:int num;int age;float score;//静态数据成员,累计学生的总分static float sum; //静态数据成员,累计学生的人数static int count;
};
//在全局作用域对静态数据成员初始化,如果不赋予初值,则使用其默认值零
float Student::sum;
int Student::count;
//定义非静态成员函数
void Student::total()
{//累加总分sum+=score;//累计已统计的人数count++;
}
//定义静态成员函数
float  Student::average()
{return(sum/count);
}
int main()
{Student stud[3]={    //定义对象数组并初始化Student(1001,18,70),Student(1002,19,78),Student(1005,20,98)
};
int n;
std::cout<<"please input the number of students: ";//输入需要求前面多少名学生的平均成绩
std::cin>>n;
//调用3次total函数
for(int i=0;i<n;i++)
{stud[i].total();
}
//调用静态成员函数
std::cout<<"the average score of "<<n<<" students is "<<Student::average( )<<std::endl;
return 0;
}

打印输出如下:

对上面的代码做以下说明:

首先,在主函数中定义了对象数组,存放每个学生的编号、年龄和成绩,其中sum和count是要累计所有学生的总成绩和总的学生人数,我们定义成了静态数据成员,在学生类的成员函数中,我们定义了普通的total成员函数,用来计算所有学生的总成绩和总的学生人数,另外,定义了静态成员函数average,学生类的设计大概如此

在全局作用域对类中静态数据成员进行了定义,但未赋予初值,这意味着我们采用其默认值。

在类的普通成员函数toal中可以引用静态数据成员sum和count,可见类的所有成员函数都可以引用类的静态数据成员。

在类的静态成员函数average中,只能引用类的静态数据成员,不能引用非静态数据成员。

在主函数中我们调用类的非静态成员函数时只能通过类对象来调用,如stu[i].total,但是对于静态成员函数可以直接通过类名+作用域符号来调用,如

Student::average。

静态数据成员和静态成员函数相关推荐

  1. 静态数据成员与静态成员函数

    3-6 静态数据成员与静态成员函数 Time Limit: 1000MS Memory limit: 65536K 题目描述 通过本题目的练习可以掌握静态数据成员和静态成员函数的用法 要求设计一个点类 ...

  2. 3-6 静态数据成员与静态成员函数

    3-6 静态数据成员与静态成员函数 Time Limit: 1000MS Memory Limit: 65536KB Submit Statistic Problem Description 通过本题 ...

  3. C++学习(五) 静态数据成员和静态成员函数

    文章目录 1.静态成员: 1.1.说明 1.2.格式 2.静态成员函数 2.1.说明 2.2.格式 1.静态成员: 1.1.说明 静态成员包括静态数据和静态成员函数. (1).静态数据成员的定义与普通 ...

  4. 类的静态数据成员和静态成员函数

    一.什么是类的静态成员 静态成员变量和全局变量都存储在全局/静态区,它们都是在程序编译时创建,直到编译结束才被收回.所以全局变量和静态成员变量的功能差不多,只是创建的方式不同,类的静态成员创建在类中, ...

  5. C++类的静态数据成员和静态成员函数

    目录 公有属性 静态数据成员 静态成员函数 公有属性 一些类对象可能会具有一些相同的属性,如果用普通数据成员来描述这些相同的属性,这意味着我们需要给每个对象的这个数据成员设定相同的值,如果改变类对象相 ...

  6. [C++] 类的静态成员 (静态数据成员 和 静态成员函数)

    目录 一.声明静态成员: 二.定义静态成员: 三.使用类的静态成员: 四.静态成员类内初始化: 五.静态成员与普通成员的区别: 六.案例代码: 类内的静态成员包括: 静态数据成员 和 静态成员函数. ...

  7. 静态数据成员和静态成员函数(static)

    目录 一.关于静态成员 二.静态数据成员和普通数据成员的共同点 三.为什么要使用静态数据成员 四.关于静态数据成员的初始化 五. 静态成员的访问方式 六.静态成员函数 1.与静态数据成员不同,静态成员 ...

  8. 【C++之静态数据成员和静态成员函数】计算商品总销售款和平均售价

    题目要求 商店销售某一商品,商店每天公布统一的折扣(discount).同时允许销售人员在销售时灵活掌握售价(price),在此基础上,对一次购 10 件以上者,还可以享受 9.8 折优惠.现已知当天 ...

  9. c++之静态数据成员与静态成员函数

    什么是静态数据成员? 数据成员我们之前学过,是对象的属性. 同一个类,不同的对象,可能拥有不同的属性 例如一个车行,不同的车有不同的颜色,不同的耗油量...等等属性 但是当我们统计一个公有的数据,用数 ...

最新文章

  1. jquery.autocomplete自动补全功能
  2. OpenJudge百炼习题解答(C++)--题4010:2011
  3. 【概念原理】四种SQL事务隔离级别和事务ACID特性
  4. php 数组存入mysql_PHP将数组存入数据库中的四种方式
  5. dwz中弹出的窗口页面如何获取前页面(点击按钮的页面)的元素???
  6. leetcode306. 累加数(回溯)
  7. java打印调用堆栈的方式
  8. python分治算法_分治法及其python实现例子
  9. Linux中的.bash_ 文件的详细说明
  10. es6 Null 传导运算符
  11. Java成神之路——javaAgent(插桩,attach)
  12. ifs 报表开发手册_店长工作手册:连锁总部店长复制手册之店长手册对门店经营管理的编写...
  13. python3语法都相同吗_Python 3.3.0的语法和3.0以前的版本有什么不一样的吗?
  14. 第十三章 线程安全与锁优化
  15. 如何实现扫码登陆 扫码登陆原理
  16. 微机原理与接口技术考点一文全(待更)
  17. shapefile文件格式说明
  18. 某智能化小区网络规划及设计
  19. 怎么把计算机的网络设置为家庭网络连接不上,win7无法设置家庭网络怎么办_教你解决win7无法设置家庭组的方法...
  20. python怎么过滤标点符号大全_一行Python代码过滤标点符号等特殊字符

热门文章

  1. 组合数学 part1
  2. python去重算法_使用Python检测文章抄袭及去重算法原理解析
  3. 虹科分享|Celerity™ 光纤通道卡(FC HBA)功能一览
  4. Gated-SCNN: Gated Shape CNNs for Semantic Segmentation论文笔记
  5. 阿里云SDK上传视频
  6. 程序员常用英语词汇(034)
  7. STM32—PID控制在直流电机中的应用
  8. 仿自适应某下载站源码
  9. 东北大学计算机学院李捷,计算机与通信工程学院第四次学生代表大会暨第十届院属学生组织换届表彰大会顺利举行...
  10. ZeroMQ指南:第4章:可靠的请求-应答