当前课程知识点:C++语言程序设计基础 >  第5章 数据的共享与保护 >  类的静态成员 >  静态函数成员(例5-5)

返回《C++语言程序设计基础》慕课在线视频课程列表

静态函数成员(例5-5)在线视频

静态函数成员(例5-5)

静态函数成员

l类外代码可以使用类名和作用域操作符来调用静态成员函数。

l静态成员函数主要用于处理该类的静态数据成员,可以直接调用静态成员函数。

l如果访问非静态成员,要通过对象来访问。

例5-5具有静态数据、函数成员的 Point类

#include <iostream>

using namespace std;

class Point {    

public:      

       Point(int x = 0, int y = 0) : x(x), y(y) {  count++; }//构造函数

                        

       Point(Point &p) {    //复制构造函数

           x = p.x;

           y = p.y;

           count++;

       }

       ~Point() {  count--; }

       int getX() { return x; }

       int getY() { return y; }

       static void showCount() {   

      cout << "  Object count = " << count << endl;

       }

 

private:     

       int x, y;

       static int count;       //静态数据成员声明用于记录点的个数

};

 

int Point::count = 0;//静态数据成员定义和初始化使用类名限定

 

int main() {      

       Point a(4, 5);     //定义对象a其构造函数回使count1

       cout << "Point A: " << a.getX() << ", " << a.getY();

       Point::showCount();       //输出对象个数

 

       Point b(a); //定义对象b其构造函数回使count1

       cout << "Point B: " << b.getX() << ", " << b.getY();

       Point::showCount();       //输出对象个数

 

       return 0;

}


下一节:类的友元(例5-6)

返回《C++语言程序设计基础》慕课在线视频列表

静态函数成员(例5-5)课程教案、知识点、字幕

大家好

欢迎回来继续学习

C++语言程序设计

这一节我给大家介绍

静态函数成员

我们只是有了静态数据成员

那用什么函数

来处理这个静态数据呢

我们在此之前呢

定义了这些函数成员

都是属于对象的

比如说

我们要取出这个点的x坐标

y坐标

getx gety

像这样的函数

它肯定是一定与某个对象相关

每次调用这样的函数的时候

都要通过对象去调用

然后这个函数呢

它可以获得这种信息

是哪个对象调用了它

所以当你调用getx的时候

它肯定知道

把哪个对象的x坐标返回

它不回弄错的

但是现在我们定义了

类的静态数据成员以后

它不属于任一个对象

那该用什么样的函数去处理它呢

一般来说

我们就要相应的定义

静态的函数成员

来处理静态数据

静态函数跟非静态成员函数

它们之间的差别在哪儿呢

差别就在

当你进到函数体以后

这个函数体里面

能不能自己知道

是哪个对象调用了它

对于非静态的

属于对象的函数

它就能够知道谁调用了它

不是说哪个主调函数调用了它

是通过哪个对象调用了它

我们用对象名.函数名

去调用这个成员函数

那么静态函数呢

即使你也用

对象名.函数名的方式

去调用这个静态函数

它就不能知道

是通过哪个对象调用了它

所以静态成员函数

一般是不用来处理

这些属于对象的数据

像每个对象的x坐标 y坐标

这种数据

是不用来处理这种数据的

它是一般是专门用来处理

属于整个类的静态数据的

如果你一定要用

一个静态的成员函数

去处理非静态的数据成员

那你就得将

希望它处理的这个对象

作为参数传给它

这种差别

大家学了第六章以后

就会明白

它到底为什么了

到底为什么呢

为什么还有的函数能知道

是哪个对象调用了它

有的函数又不知道呢

实际上调用非静态函数的时候

隐含地将当前对象的某种信息

传给了它

这件事好象很神秘

怎么能隐含就传过去呢

大家不要急

第六章就给大家介绍

现在我们知道一般的规律是

类里如果需要静态数据成员的话

相应地我们定义静态的函数成员

去处理它

现在我们还是通过例题

来理解一下静态函数成员

这一次我们在Point类里面

就增加了一个静态函数成员

实际上这是前一个例子里面那个

显示点的总数的那个函数

当时没有作为静态成员来定义

现在我们加一个static

就把它作为静态成员

那我们来看看

这个类的类图

那么我们看

在这个类的类图中呢

最底下showCount这个函数

前面有个关键字static

就表示它是个静态成员

现在呢我们来看一下

这个类的代码

现在我们来看这个例题

这个例题在前一个例题的基础上

做了一点小小的修改

大部分都还是一样的

我们先看它的私有数据成员定义

还是有一个静态的变量count

用于记录点的个数

非静态的变量x y

表示每一个对象的x坐标 y坐标

这个静态成员呢

仍然是在类外定义和初始化

但是不同的是什么呢

我们在这儿

将这个showCount函数

也定义成静态的了

那么静态的函数

也是为整个类的所有对象

共有的函数

那么大家在这一点上呢

可能有些疑问

不是所有的函数都只有

在类里面的这种声明和定义

只有一份有效

不赋值多份存在对象名下

每个对象的存储空间

就是它自己的数据成员占的空间

函数代码没有存多份呢

怎么表现出这是个静态函数

是为整个类所共享的

那个是非静态函数

是属于某一个对象的呢

我们来看

这个函数它都干些什么

比如说像构造函数

赋值构造函数

它都是在构造

某一个特定对象的时候起作用

我们来看它给x作初始化

给y变量作初始化

这个赋值构造

赋值给x

参数对象的y赋值给y

这个操作的都是指定对象的成员

像这个getx gety

也是将指定对象的成员返回

那我们看调用的时候呢

像a.getx

那么它就知道

要将a对象的x坐标返回

为什么呢

我们在第六章将要讲指针

讲了指针以后会告诉大家

对于非静态的函数

实际上是有一个

类似指针传过去的

而静态函数通常用来

执行什么任务呢

通常用来处理静态数据成员

你可不能指望

在showCount函数里面

说输出点的x坐标 y坐标

千万不能那么写

为什么呢

你要是说在showCount函数里面

要输出x坐标

它去输出谁的x坐标 对吧

这个类有那么多点构造出来了

你让showCount这个静态函数

属于整个类

而不属于对象的函数

去输出一个x坐标

是不是完全不可以呢

也不是

你如果一定要让它输出

某个对象的x坐标

你就得显示的将这个对象

作为参数传给showCount

不然的话你在这里面泛泛地说

cout x cout y

它根本不知道

该输出谁的x y坐标

但是你让它输出count

它就知道

因为整个类只有一个count变量

为什么是这样

相信大家在这儿一定有这个疑问

你可以做个笔记把它记下来

等我们讲完第六章

你这个疑问就解决了

第六章在这个课程的下半部

希望大家能继续学习第六章

能够真正去理解

为什么静态的函数加了static

它一般来讲

就只能访问静态数据

这个count这样的数据

好 做了这样一点点修改以后

这个题比上一个例题

用起来就方便一些了

我们来看在主函数中

在根本没有建立任何一个点之前

一个点都没有构造之前

我就可以通过类名

去调用showCount

通过类名调用showCount

就可以将当前点的总数

输出来0个

当然构造了对象以后

你再调用showCount

构造了a以后

那它就是一个对象了

构造了b以后

是两个对象了

这个时候是不是大家还有疑问

我现在只能用类名

去调用showCount函数吗

我能不能仍然用对象名去调用它

也可以

大家课后可以把这个例题

修改一下

你试试在这个地方

写a.showCount

在这个地方写b.showCount

看看它是不是也能正确的编译

运行是不是也能出正确的结果呢

应该是能正确的

所以一个静态的成员函数

我们既可以通过类名

作用域分辨符去调用它

也可以通过

对象名.函数名的方式去调用它

都是可以的

C++语言程序设计基础课程列表:

第1章 绪论

-导学

--第1章导学

-计算机系统简介

--计算机系统简介

--计算机系统简介 测试题

-计算机语言和程序设计方法的发展

--计算机语言和程序设计方法的发展

--计算机语言和程序设计方法的发展 测试题

-面向对象的基本概念

--面向对象的基本概念

--面向对象的基本概念 测试题

-程序的开发过程

--程序的开发过程

--程序的开发过程 测试题

-信息的表示和储存

--计算机中的信息与存储单位

--计算机的数字系统

--数据的编码表示

--信息的表示和储存 测试题

-实验指导

--实验一:VS开发环境介绍

第2章 C++简单程序设计(一)

-导学

--第二章导学

-C++语言概述

--C++的特点和程序实例

--C++字符集和词法记号

--C++语言概述 测试题

-基本数据类型、常量、变量

--基本数据类型、常量、变量

--程序举例

--基本数据类型、常量、变量 测试题

-运算与表达式

--算术运算与赋值运算

--逗号运算、关系运算、逻辑运算和条件运算

--Sizeof运算、位运算

--运算优先级、类型转换

--运算与表达式 测试题

-实验二:简单程序设计(上)

--实验二:简单程序设计(上)

第2章 C++简单程序设计(二)

-数据的输入和输出

--数据的输入和输出

--数据的输入和输出 测试题

-选择结构

--if语句

--switch语句

--选择结构 测试题

-循环结构

--循环结构——while语句

--do-while语句

--for语句

--嵌套的控制结构、其他控制语句

--循环结构 测试题

-自定义类型

--自定义类型

--自定义类型

-第2章小结

--第二章小结

-实验二:C++简单程序设计(下)

--实验二C++简单程序设计(下)

第3章 函数

-导学

--导学

-函数定义

--函数定义

--函数定义 测试题

-函数调用

--函数调用(例3-1)

--例3-2

--例3-3

--例3-4

--例3-5

--例3-6

--函数调用 测试题

-嵌套与递归

--函数的嵌套调用(例3-7)

--函数的递归调用(例3-8)

--例3-9

--例3-10

--嵌套与递归 测试题

-函数的参数传递

--函数的参数传递

--函数的参数传递 测试题

-引用类型

--引用类型(例3-11)

--引用类型 测试题

-含有可变参数的函数

--含有可变参数的函数

--含有可变参数的函数 测试题

-内联函数

--内联函数(例3-14)

--内联函数 测试题

-constexpr函数

--constexpr函数

--CONSTEXPR函数课后习题

-带默认参数值的函数

--带默认参数值的函数

--默认参数值例(3-15)

--带默认参数值的函数 测试题

-函数重载

--函数重载(例3-16)

--函数重载 测试题

-C++系统函数

--C++系统函数(例3-17)

--C++系统函数习题

-第3章小结

--第三章小结

-实验三(上)函数的应用

--实验三(上)函数的应用

-实验三(下)函数的应用

--实验三(下)函数的应用

第4章 类与对象

-导学

--导学

-面向对象程序的基本特点

--面向对象程序的基本特点

--面向对象程序的基本特点 测试题

-类和对象

--类和对象的定义

--类和对象的程序举例

--类和对象 测试题

-构造函数

--构造函数基本概念

--构造函数例题(1)——例4-1

--构造函数例题(2)——例4-2

--委托构造函数

--复制构造函数

--复制构造函数调用举例

--构造函数 测试题

-析构函数

--析构函数

--析构函数 测试题

-类的组合

--类的组合

--类的组合程序举例

--前向引用声明

--类的组合 测试题

-UML简介

--UML简介

--UML简介课后习题

-结构体与联合体

--结构体(例4-7)

--联合体(例4-8)

--结构体与联合体 测试题

-枚举类

--枚举类

--枚举类 测试题

-第4章小结

--第四章小结

-实验四(上)

--实验四(上)

-实验四(下)

--实验四(下)

第5章 数据的共享与保护

-导学

--导学

-标识符的作用域与可见性

--标识符的作用域与可见性

--标识符的作用域与可见性 测试题

-对象的生存期

--对象的生存期

--对象的生存期 测试题

-类的静态成员

--静态数据成员(例5-4)

--静态函数成员(例5-5)

--类的静态成员 测试题

-类的友元

--类的友元(例5-6)

--类的友元 测试题

-共享数据的保护

--共享数据的保护(例5-7)

--共享数据的保护 测试题

-多文件结构和预编译命令

--多文件结构和预编译命令(例5-10)

--多文件结构和预编译命令 测试题

-第5章小结

--小结

-实验五

--实验五

第6章 数组、指针与字符串(一)

-导学

--导学

-数组的定义与初始化

--数组的定义与使用

--数组的储存与初始化

--一维数组应用举例

--数组的定义与初始化 测试题

-数组作为函数的参数

--数组作为函数参数(例6-2)

--数组作为函数的参数 测试题

-对象数组

--对象数组

--对象数组 测试题

-基于范围的for循环

--基于范围的for循环

-指针的定义和运算

--指针的概念、定义和指针运算

--指针的初始化和赋值

--指针的算术运算、关系运算

--指针的定义和运算 测试题

-综合实例

--综合实例

-实验六(上)

--实验六上

第6章 数组、指针与字符串(二)

-指针与数组

--用指针访问数组元素

--指针数组

--指针与数组 测试题

-指针与函数

--以指针作为函数参数

--指针类型的函数

--指向函数的指针

--指针与函数 测试题

-对象指针

--对象指针

--对象指针 测试题

-动态内存分配

--动态分配与释放内存

--申请和释放动态数组(一)

--申请和释放动态数组(二)

--动态内存分配 测试题

-智能指针

--智能指针

-vector对象

--vector对象

--vector对象 测试题

-对象复制与移动

--深层复制与浅层复制

--移动构造

--对象复制与移动 测试题

-字符串

--C风格字符串

--string类

--字符串 测试题

-第6章小结

--第六章小结

-综合实例

--综合实例

-实验六(下)

--实验六(下)

静态函数成员(例5-5)笔记与讨论

也许你还感兴趣的课程:

© 柠檬大学-慕课导航 课程版权归原始院校所有,
本网站仅通过互联网进行慕课课程索引,不提供在线课程学习和视频,请同学们点击报名到课程提供网站进行学习。