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

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

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

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

l静态数据成员

n  用关键字static声明

n  为该类的所有对象共享,静态数据成员具有静态生存期。

n  必须在类外定义和初始化,用(::)来指明所属的类。

 

l例5-4 具有静态数据成员的Point类




//5_4.cpp

#include <iostream>

using namespace std;

class Point {     //Point类定义

public:       //外部接口

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

           //在构造函数中对count累加所有对象共同维护同一个count

           count++;

       }

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

           x = p.x;

           y = p.y;

           count++;

       }

       ~Point() {  count--; }

       int getX() { return x; }

       int getY() { return y; }

      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();

       a.showCount(); //输出对象个数

 

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

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

       b.showCount();       //输出对象个数

       return 0;

}

 

运行结果:

 Point A: 4, 5  Object count=1

 Point B: 4, 5  Object count=2


下一节:静态函数成员(例5-5)

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

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

大家好

欢迎回来继续学习

C++语言程序设计

这一节

我给大家介绍类的静态数据成员

我们知道类的静态成员

它是用static修饰的

属于整个类

而不属于对象的

那么类的静态数据成员呢

就是为类的所有对象

所共享的数据

它的声明要放在类体里面

但是它的定义和初始化

要放在类外

现在我们来看一个

静态数据成员的例子

这个例子是一个

具有静态数据成员的Point类

我们在前面例子中

看到这个Point类

它的数据成员就是一个x坐标

一个y坐标

但是如果我们想存放点的总数

怎么存放呢

也就是说

我们希望能够记录一下

到某个时刻为止

一共在这个系统中

构造了多少个Point对象

这个数值要记录在哪儿呢

当然由于它是与Point类相关的

肯定我们要想到

它应该放在Point类里面

但是它又不应该

放在每一个对象里面

每一个对象要负责存储

自己的x坐标 y坐标

但是每一个对象不应该去存储

整个类现在

一共有多少个对象这件事

所以呢像这样的数据

就是属于整个类

为整个类的所有对象所共有

那么就应该把它定义成

类的静态成员

类的静态成员在定义的时候

要加一个static关键字来修饰

我们看这个是Point类的类图

在这里面呢

我们看到有一个count成员

那么它是类的静态成员

接下来呢

我们来看一下

这个Point类的代码

现在我们通过这个例子

来观察一下类的静态数据成员

这是一个点类的定义

我们定义好一个点类以后

可以在需要的时候

构造很多点的对象

那么这个时候如果需要

存储点的总数

那么这样一个变量呢

作为类的静态变量就比较合适

所以呢在这个点类中

Point类中

我们定义了一个静态变量count

这个count在类体里面只是声明

count的定义以及初始化

要放在类体之外 在这儿

除了这个静态成员以外

还有非静态的数据成员x和y

这个非静态的成员x y呢

就属于每一个点了

每一个点都要有个x坐标 y坐标

但是每一个点

不会存储这个count值

这个count值只在整个类中

存储一份

然后我们看这个类里面

它在构造函数中

就要给count进行更新

每构造一个点

点的总数就要加1

我们看复制构造函数中也是

复制构造函数也是构造了

也要给点数加1

析构函数中呢

就要给点的总数减1

那么学第四章的时候

是不是有的同学还觉得

这个析构函数有什么用啊

老觉得它没有用

空函数体写它干什么

现在你看到

在这个例题中

析构函数有用了吧

每一个点当它消亡的时候

都会执行析构函数

这个时候就是特别合适的地方

给点数减1的地方

而且从这些例题我们会看到

很多时候

一般来讲很多操作

在构造函数跟析构函数中

都是相对的

比如说构造函数中

给点的总数加1

那么析构函数呢

就要给点的总数减1

以后我们还会看到

更多这样的例子

其他的函数呢

跟我们以前的例子中

看到的都是一样的

只不过这儿呢

多了一个函数 showCount

就是显示一下

目前一共有多少个点了

大家看输出这个count

showCount是一个普通的函数

不是静态函数

通过每一个点都可以调用它

那也就是说

通过每一个点都可以去访问

这个count变量

接下来我们看一下

在主函数中是怎么应用

在主函数中

首先构造了一个点

它初始化坐标是4和5

x是4 y是5

然后接下来我们验证一下

输出一下点a的x坐标 y坐标

大家看这里

输出结果看到了

好 那接下来就通过a

去调用showCount

showCount这个非静态的函数

是要通过对象来调用的

这种消息是要发给对象的

那么通过对象调用showCount

就可以显示目前点的个数是多少

我们看到

这儿点的个数输出是1

下面又通过复制构造函数

去初始化了一个新的点b

让它跟a一样

同样呢构造完了以后

输出它的x值 y值

验证一下看

x坐标和y坐标跟a是一样的

复制构造

效果就应该是这样的

接下来通过b

再次调用showCount

我们可以看到

通过每一个对象

都可以去调用showCount

这个函数

都可以得到当前点的总数

那么通过b去调用showCount呢

看到点的总数是2

为什么呢

因为我们构造a的时候

调用的是构造函数

在这里面给count给增了1

构造点b的时候

调用了复制构造函数

也给count增1

它们操作的

都是同一个静态变量count

所以构造完了b

这个count的值输出就是2了

当我们离开这个主函数的时候

也就是说程序要结束的时候

对象a 对象b

都要被析构的

它们的存储空间都要被释放

所以都要被析构的

这个时候就会调用析构函数

每析构一个变量呢

将点的总数减1

所以通过这个例题我们看到了

可以在类里面

定义一个静态的变量

用来为整个类的所有对象所共享

存这种共享的数据

但是现在我问一个问题

大家看怎么解决

也就是说

在主函数中

当我一个点都没有的时候

我能不能问一问现在有几个点了

0个吗 对吧

a也没有构造 b也没有构造

一个点都没有的时候

是不是我可以查询一下

现在有多少个点

是不是也应该能够告诉我

现在点的个数是0呢

看看现在这个类

有办法做到这一点吗

做不到

为什么

count这个变量是私有成员

所以在类外是不能直接访问的

那好 通过公有接口访问呢

通过showCount访问呢

但你怎么调用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-4)笔记与讨论

也许你还感兴趣的课程:

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