C++数据的共享与保护

C++数据的共享与保护

1.导学

变量和对象定义在不同的位置

(函数体内、类体内、函数原型参数表内、所有函数和类之外)

其作用域、可见性、生存期都不同 。

属于整个类的数据成员————静态数据成员

用于处理静态数据成员的函数————静态成员函数

友元:对一些类外的函数、其他的类,给与授权,使之可以访问类的私有成员。

通过const关键字,限制对共享数据的修改。

多文件结构

2.标识符的作用域与可见性

作用域的分类:

(1)函数原型作用域

​ 函数原型中的参数

​ 其作用域始于"(",结束于")"

函数原形作用域举例:
double area(double radius);
注意:radius的作用域仅在于此,不能用于程序正文其他地方

(2)局部作用域(块作用域)

​ 函数的形参、在块中声明的标识符;

​ 作用域自声明处起,限于块中。

void fun(int a){
int b=a;
cin>>b;
if(b>0){
int c;
}
}

(3)类作用域

类的成员具有类的作用域,其范围包括类体和成员函数体。

在类的作用域以外访问类的成员:

静态成员:通过类名,或者该类的对象名、对象引用访问。

非静态成员:通过类名,或者让人该类的对象名、对象引用、对象指针访问。

(4)文件作用域(静态作用域)

​ 不再前述各个作用域中的声明,就具有文件作用域;

​ 其作用域开始于声明点,结束于文件尾。

可见性

可见性是从对标识符的引用的角度来谈的概念

可见性表示从内层作用域向外层作用域“看”时能看见

如果标识在某处可见,就可以在该处引用此标识符。

(5)命名空间作用域

例:

#include"iostream"
using namespace std;
 
int i;//全局变量,文件作用域
int main() {
	i = 5;//全局变量i赋值
	{
		int i;//局部变量,局部作用域
		i = 7;
		cout << "i=" << i  << endl;//输出7
	}
	cout << "i=" << i << endl;//输出5
	return 0;
}
运行结果:
          i=7
          i=5

3.对象的生存期

对象的生存期

对象从产生到结束的这段时间就是它的生存期

在对象生存期内,对象将保持它的值,直到被更新为止。

静态生存期

这种生存期与程序的运行期相同。

在文件作用域中声明的对象具有这种生存期。

在函数内部声明静态生存期对象,要冠以关键字static

动态生存期

开始于程序执行到声明点时,结束于命名该标识符的作用域结束处。

块作用域声明的,没有static修饰的对象是动态生存期的对象(习惯称局部生存期对象)

例:
#include"iostream"
using namespace std;
int i = 1;//i为全局变量,具有静态生存期。
void other() {
	static int a = 2;
	static int b;
	//a,b为静态局部变量,具有全局寿命,局部可见。
	//只有第一次进入函数时被初始化。
	int c = 10;//c为全局变量,具有动态生存期,每次进入函数时都初始化
	a += 2; i += 32; c += 5;
	cout << "---OTHER---\n";
	cout << "i:" << i << "a:" << a << "b:" << b << "c:" << c << endl;
	b = a;
}
int main() {
	static int a;//静态局部变量,有全局寿命,局部可见。
	int b = -10;//b,c为局部变量,具有动态生存期。
	int c = 0;
	cout << "---MAIN---\n";
	cout << "i:" << i << "a:" << a << "b:" << b << "c:" << c << endl;
	c += 8; other();
	cout << "---MAIN---\n";
	cout << "i:" << i << "a:" << a << "b:" << b << "c:" << c << endl;
	i += 10; other();
	return 0;
}
运行结果:
---MAIN---
i:1a:0b:-10c:0
---OTHER---
i:33a:4b:0c:15
---MAIN---
i:33a:0b:-10c:8
---OTHER---
i:75a:6b:4c:15

4.类的静态数据成员

静态数据成员

用关键字static声明

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

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

例:静态成员举例
#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 << "Objet count=" << count << endl;
	}
private://私有数据成员  
		int x, y;
	static int count;//静态数据成员声明,用于记录点的个数
};
int Point::count = 0;//静态数据成员定义和初始化,使用类名限定
int main() {//主函数
	Point a(4, 5);//定义对象a,其构造函数回使count增1
	cout << "Point A:" << a.getX() << "," << a.getY();
	a.showCount();//输出对象个数

	Point b(a);//定义对象b,其构造函数回使count增1
	cout << "Point B:" << b.getX() << "," << b.getY();
	b.showCount();//输出对象个数
	return 0;
}
运行结果:
Point A:4,5Objet count=1
Point B:4,5Objet count=2

5.类的友元

类的友元

友元是C++提供的一种破环数据封装和数据隐藏的机制。

通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息。

  • 可以声明友元函数的友元类。

  • 为了声明友元函数和友元类。

  • 为了确保数据的完整性,及数据封装与隐藏的原则。

友元函数

友元函数是在类声明中由关键字friend修饰说明的成员函数,在它的函数体中能够通过对象

#include"iostream"
#include"cmath"
class Point {//Point类声明
public://外部接口
	Point(int x = 0, int y = 0) :x(x), y(y) {}
	int getX() { return x; }
	int getY() { return y; }
	friend float dist(Point& a, Point& b);
private://私有成员
	int x, y;
};
float dist(Point& a, Point& b) {
	double x = a.x - b.x;
	double y = a.y - b.y;
	return static_cast<float>(sqrt(x * x + y * y));
}
int main() {
	Point p1(1, 1), p2(4, 5);
	cout << "The distance is:";
	cout << dist(p1, p2) << endl;
	return 0;
}
运行结果:
The distance is:5

类的友元关系是单向的:声明B类是A类的友元不等于A类是B类的友元

6.共享数据的保护

常类型

*常对象:*必须进行初始化,不能被更新。

const 类名 对象名;

常成员

用const进行修饰的类成员:常数据成员和常函数成员。

常成员函数

​ 使用const关键字说明的函数

​ 常成员函数不更新对象的数据成员。

​ 常成员函数说明格式:

​ 类型说明符 函数名 (参数表)const;

​ const是函数类型的一个组成部分,在实现部分也要带const关键字。

​ const关键字可以被用于参与对重载数据的区分

​ 通过常对象只能调用它的常成员函数。

#include"iostream"
using namespace std;
class R {
public:
	R(int r1, int r2):r1(r1), r2(r2) {}
	void print();
	void print() const;
private:
	int r1, r2;
};
void R::print() {
	cout << r1 < ":" << r2 << endl;
}
void R::print() const{
	cout << r1 < ";" << r2 << endl;
}
int main() {
	R a(5, 4);
	a.print();//调用void print()
	const R b(20, 52);
	b.print();//调用void print() const
	return 0;
}
运行结果:
54
2052

常数据成员

​ 使用const说明的数据成员。

#include"iostream"
using namespace std;
class A {
public:
	A(int i);
	void print();
private:
	const int a;
	static const int b;//静态常数据成员
};
const int A::b = 10;
A::A(int i) :a(i) {}
void A::print() {
	cout << a << ":" << b << endl;
}
int main() {
//建立对象a和b,并以100和0作为初值,分别调用构造函数
//通过构造函数的初始化列表给对象的常数据成员赋初值
	A a1(100), a2(0);
	a1.print();
	a2.print();
	return 0;
}
运行结果:
100:10
0:10

*常引用:*被引用的对象不能被更新。

const 类型说明符 &引用名;

**注意:**在友元函数中用常引用做参数,即能获得较高的执行效率,又能保证实参的安全性。

#include"iostream"
#include"cmath"
using namespace std;
class Point {//Point类定义
public://外部接口
	Point(int x = 0, int y = 0) :x(x), y(y) {}
	int getX() { return x; }
	int getY() { return y; }
	friend float dist(const Point& p1, const Point& p2);
private://私有数据成员
	int x, y;
};
float dist(const Point& p1, const Point& p2) { {}
double x = p1.x - p2.x;
double y = p1.y - p2.y;
return static_cast<float>(sqrt(x * x + y * y));
}
int main() {
	const Point myp1(1, 1), myp2(4, 5);
	cout << "The distance is:";
	cout << dist(myp1, myp2) << endl;
	return 0;
}
运行结果:
The distance is:5

常数组:数组元素不能被更新

类型说明符 const 数组名[大小]…

常指针:指向常量的指针

7.多文件结构和预编译命令

C++程序的一般组织结构

一个工程可以划分为多个源文件,例如:

类声明文件(.h文件)

类实现文件(.cpp文件)

类的使用文件(main()所在的.cpp文件)

利用工程来组合各种文件

外部变量

除了定义它的源文件中可以使用外,还能被其他文件使用。

文件作用域中定义的变量,默认情况下都是外部变量

在其他文件中如果需要使用,需要用extern关键字声明

外部函数

在所有类之外声明的函数(也就是非成员函数),都具有文件作用域的。

标准C++库

标准C++类库是一个极为灵活并可扩展的可重用软件模块的集合。

标准C++类与组件在逻辑上分为6种类型:

(1)输入/输出类

(2)容器类与抽象数据类型

(3)存储管理类

(4)算法

(5)错误处理

(6)运行环境支持

编译预处理

#include 包含指令

将一个源文件嵌入到当前源文件中该点处。

#include<文件名>

按标准方式搜索,文件位于C++系统目录的include子目录下

#include"文件名"

首先在当前目录中搜索,若没有,在按标准方式搜索。

#define 宏定义指令

定义符号常量,很多情况下已被const定义语句取代。

定义带参数宏,已被内联函数取代。

#undef

删除由#define定义的宏,使之不再起作用。

条件编译------#if和#endif

#if 常量表达式

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值