清华大学C++课程学习笔记——第五章 数据共享与共享数据的保护
(一)数据的特点
1.作用域:
作用域名称(由小到大) | 作用域范围 |
---|---|
函数原型作用域 | 函数原型中的参数,作用域开始于“(”,结束于“)” |
局部作用域 | 函数的形参,在块中声明的标识符{} |
类作用域 | 范围包括类体和成员函数体 |
文件作用域 | 不在各个作用域出现的声明就具有文件作用域,开始于声明点,结束于文件尾 |
2.可见性
从引用的角度来谈的概念,标识符在某处见,就可以在该处引用此标识符;
如果某个标识符在外层中声明, 且在内层中没有同一标识符声明,则该标识符在内层可见;
对于两个嵌套的作用域,内层声明了与外层作用域同名的标识符,则外层作用域的标识符在内层不可见。
【总结:内层作用域的优先级更高】
# include<iostream>using namespace std;int i; //全局变量,文件作用域int main(){i = 5;{int i;i = 7;//局部变量,局部作用域cout<<"i="<<i<<endl; }cout<<"i="<<i<<endl;return 0;}
结果输出
i=7
i=5
3.生存期
生存期名称 | |
---|---|
静态生存期 | 在文件作用域中声明的对象;具有这种生存期、在函数内部声明静态生存期对象,要冠以关键字static |
动态生存期 | 开始于程序执行到声明点时,结束于命名该标识符的作用域技术处;块作用域中声明的,没有赢static修饰的对象,动态生存期的对象eg.函数体里定义的变量 |
对比:静态生存期的变量即使离开了作用域也仍然保存着
# include<iostream>
using namespace std;
int i = 1; //i为全局变量,具有静态生存期void other(){static int a = 2;static int b = 3;//a,b为静态全局变量,具有全局寿命,局部可见//只第一次进入函数时被初始化int c = 10;//c为局部变量,具有动态生存期,每次进入函数时都被初始化a+=2;i+=32;c+=5;cout<<"i=:"<<i<<endl;cout<<"a=:"<<a<<endl;cout<<"b=:"<<b<<endl;cout<<"c=:"<<c<<endl;
}int main(){static int a; //静态局部变量,全局寿命,局部可见int b = -10; //b,c为局部变量,具有动态生存期int c = 0;cout<<"---main---"<<endl;cout<<"i=:"<<i<<endl;cout<<"a=:"<<a<<endl;cout<<"b=:"<<b<<endl;cout<<"c=:"<<c<<endl;c+=8;i+=10;cout<<"---other---"<<endl;other();return 0;
}
输出结果
i=:1
a=:0
b=:-10
c=:0
---other---
i=:43
a=:4
b=:3
c=:15
变量和对象定义在不同位置
(作用域、可见性、生存期)
(二)数据共享
1.属于整个类的数据成员——静态数据成员
用关键字static声明;为该类的所有对象共享,静态数据成员具有静态生存期;
必须在类外定义和初始化,用(::)来指明所属的类。
eg:记录点的个数count,程序的小问题在没有点数的时候
#include <iostream>
using namespace std;
class Point //Point类定义
{public: //外部接口Point(int xx=0, int yy=0) {X=xx; Y=yy; countP++; } //构造函数Point(Point &p); //拷贝构造函数~Point(){ countP--; }int GetX() {return X;}int GetY() {return Y;}void GetC() {cout<<" Object id="<<countP<<endl;} //输出静态数据成员
private: //私有数据成员int X,Y;static int countP; //静态数据成员引用性说明,用于记录点的个数
};
Point::Point(Point &p)
{X=p.X;Y=p.Y;countP++; //在构造函数中对countP累加,所有对象共同维护同一个countP
}int Point::countP=0; //静态数据成员定义性说明和初始化,使用类名限定
int main() //主函数
{Point A(4,5); //定义对象A,其构造函数回使countP增1cout<<"Point A,"<<A.GetX()<<","<<A.GetY();A.GetC(); //输出对象个数Point B(A); //定义对象B,其构造函数回使countP增1cout<<"Point B,"<<B.GetX()<<","<<B.GetY();B.GetC(); //输出对象个数return 0;
}
2.静态函数成员
背景:之前定义的成员函数是属于对象的,静态函数成员主要用于处理该类的静态数据。
(调用非静态函数时,隐含的传递了对象相关的信息,就是后面提到的this指针,第六章)
eg:把统计点的个数的函数加一个,解决上面例题无法输出0个点的问题,没有点就没法调用
3.友元
(1)类的友元
将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中被隐藏的信息;
破坏数据封装和数据隐藏的机制。
(2)友元函数
在类申明中用关键字friend修饰说明的非成员函数,能够通过对象名访问private和protected成员;
eg:计算两个点之间的距离,频繁使用get相关函数
问题:给有元函数传递的引用,传递引用通用的问题是容易把值改变了
(3)友元类
一个类为另一个类的友元,则此类的所有成员函数都能访问对方类的私有成员
声明语法:将友元类名在另一个类中使用friend修饰说明,类的组合与部件
总结:类的友元关系是单向的
#include <iostream>
#include <cmath>
using namespace std;
class Point //Point类定义
{public: //外部接口Point(int xx=0, int yy=0) {X=xx;Y=yy;}int GetX() {return X;}int GetY() {return Y;}friend float fDist(Point &a, Point &b); //友元函数声明,不是成员函数,所以应该把两个点都作为参数传递
private: //私有数据成员int X,Y;
};
float fDist(Point &p1, Point &p2) //友元函数实现
{ double x=double(p1.X-p2.X); //通过对象访问私有数据成员double y=double(p1.Y-p2.Y);return float(sqrt(x*x+y*y));
}
void main() //主函数
{Point myp1(1,1),myp2(4,5); //定义Point类的对象cout<<"The distance is:";cout<<fDist(myp1,myp2)<<endl; //计算两点间的距离
}
(三)共享数据的保护
1.常类型
const:一个承诺,对于不改变对象的函数,主动声明为常函数
名称 | 语法表达式 | 说明 |
---|---|---|
常对象 | const 类名 对象名 | 必须进行初始化,且不能被更新 |
常成员 | 类型说明符 函数名(参数表)const | 常数据成员和常函数成员通过常对象只能调用它的成员函数;const可用于参与对重载函数的区分;只能在初始化阶段进行赋值 |
常引用 | const 类型说明符 &引用名 | 被引用的对象不能被更新,eg友元函数中使用常引用作为参数,或得较高的执行效率,保证实参的安全性 |
常数组 | 类型说明符 const 数组名[大小] | 数组元素不能被更新 |
常指针 | 指向常量的指针 |
【牛客网经常刷到:下面const语句正确的是】
(四)多文件结构
1.组织结构
- 类声明文件(.h文件)
- 类实现文件(.cpp文件)
- 类使用文件(main()所在的.cpp文件)
利用工程文件来组合各个文件,系统中自带的头文件不带.h用"<>"在安装的默认目录下寻找
eg:# include "Point.h"
2.文件组织结构对应变量和函数的新操作
(1)外部变量
背景:由上面的文件组织结构可知,有些变量可以在多个文件中使用;文件作用域中的变量默认都是外部变量。
使用:extern
关键字
(2)外部函数
背景:所有类之外的函数(非成员函数)都是具有文件作用域的
使用:这样的的函数可以在不同的编译单元中被调用,在调用前进行引用性声明(声明函数原型)
(3)匿名空间
变量和函数进行空间限制
3.标准C++库
主要分类:输入/输出类;容器类与抽象数据类型(大批量数据,类模板的总称);存储管理类;算法;错误处理;运行环境支撑
4.编译预处理命令
#include 包含指令
- 将一个源文件嵌入到当前源文件中该点处
# include<>
按照标准方式搜索,文件位于C++系统目录的include子目录下# include""
首先在当前目录下搜索,再按标准目录搜索
#define
和#undef
#if
和#endif
和#else
清华大学C++课程学习笔记——第五章 数据共享与共享数据的保护相关推荐
- python降维将多列数据压缩为一列_Python机器学习(Sebastian著 ) 学习笔记——第五章通过降维压缩数据(Windows Spyder Python 3.6)...
数据压缩是机器学习领域中重要的内容,通过数据压缩技术可以将原始数据集变换到一个维度更低的新的特征子空间,帮助对数据存储和分析. 降维压缩数据,分为无监督和有监督两类,先来介绍无监督数据压缩--主成分分 ...
- Python机器学习(Sebastian著 ) 学习笔记——第五章通过降维压缩数据(Windows Spyder Python 3.6)...
数据压缩是机器学习领域中重要的内容,通过数据压缩技术可以将原始数据集变换到一个维度更低的新的特征子空间,帮助对数据存储和分析. 降维压缩数据,分为无监督和有监督两类,先来介绍无监督数据压缩--主成分分 ...
- 《Go语言圣经》学习笔记 第五章函数
<Go语言圣经>学习笔记 第五章 函数 目录 函数声明 递归 多返回值 匿名函数 可变参数 Deferred函数 Panic异常 Recover捕获异常 注:学习<Go语言圣经> ...
- Programming Entity Framework-dbContext 学习笔记第五章
### Programming Entity Framework-dbContext 学习笔记 第五章 将图表添加到Context中的方式及容易出现的错误 方法 结果 警告 Add Root 图标中的 ...
- 2022 最新 Android 基础教程,从开发入门到项目实战【b站动脑学院】学习笔记——第五章:中级控件
第 5 章 中级控件 本章介绍App开发常见的几类中级控件的用法,主要包括:如何定制几种简单的图形.如何使用几种选择按钮.如何高效地输入文本.如何利用对话框获取交互信息等,然后结合本章所学的知识,演示 ...
- 《Android深度探究HAL与驱动开发》学习笔记----第五章
第五章 搭建S3C6410开发板的测试环境 开发板是开发和学习嵌入式技术的主要硬件设备. 主要学习了搭建S3C6410开发板的测试环境.首先要了解到S3C6410是一款低功耗.高性价比的RISC处理器 ...
- muduo学习笔记 - 第五章 高效的多线程日志
第五章 高效的多线程日志 日志有两种意思: 诊断日志 交易日志 本章讲的是前一种日志,文本的供人阅读的日志,通常用于故障诊断和追踪,也可用于性能分析. 日志通常要记录: 收到的每条消息的id(关键字段 ...
- javascript高级程序设计 学习笔记 第五章 上
第五章 引用类型的值(对象)是引用类型的一个实例.在 ECMAScript 中,引用类型是一种数据结构, 用于将数据和功能组织在一起.它也常被称为类,但这种称呼并不妥当.尽管 ECMAScri ...
- css层叠样式表基础学习笔记--第五章 文本属性
第五章 文本属性 5-01 字间距 5-02 行高 5-03 首行缩进 5-04 水平排列方式 5-05 垂直对齐方式 5-06 文本修饰 5-07 文本阴影 5-08 文本属性重置 5-01 字间距 ...
- 程序设计与算法三~C++面向对象程序设计~北大郭炜MOOC学习笔记~第五章:继承与派生(新标准C++程序设计)
以下内容为笔者手打,望读者珍惜,如有转载还请注明. 第五章 继承与派生 $5.1 继承与派生的概念 $5.1.1 基本概念 在C++中,当定义一个新的类B时,如果发现类B拥有某个已经写好的类A ...
最新文章
- 网站怎样留住浏览用户
- BZOJ-3505-数三角形-CQOI2014
- TS对象中的实例属性和静态属性
- Git : 每一行命令都算数
- ft232h引脚_一种基于芯片ft232h的usb接口电路的制作方法
- MPLS(多协议标记交换)协议能否降低跨省组建企业专网的成本?
- linux php zend load,在Linux系统中为PHP5.3安装Zend Guard Loader
- android-sdk-windows 如何安装,android-sdk-windows 安装.doc
- linux下搭建测试环境
- MacBook重装系统
- aamp;m大学计算机科学,名校介绍丨美国 德克萨斯AM大学 Texas AM University
- vue实现table课程表
- 80211协议beacon帧字段解析一
- python和汇编_python – 你对这些汇编助记符有什么建议吗?
- 金九银十,我不允许你们不知道这些软件测试面试题
- 【系统分析与验证笔记】Transition System模型知识点
- Leetcode刷题33. 搜索旋转排序数组
- 细粒度车型识别项目(数据集Stanfordcar-196)附源代码
- 演化博弈的Python实现:基础篇2 基于复杂网络的演化博弈
- 【Python】切割PDF文件,遇到 PdfReadError: File has not been decrypted