5_数据的共享与保护

数据的共享与保护

标志符的作用域和可见性

作用域

  • 函数原型作用域:函数形参表括号
  • 局部作用域(块作用域):函数体或大括号,函数的形参
  • 类作用域:类体和成员函数体
  • 文件作用域:开始于声明点,结束于文件尾
  • 命名空间作用域
#include <iostream>
using namespace std;

int i = 0; //全局变量,文件作用域 

int main(){
	i= 5;
	{
		int i;  //局部变量,局部作用域
		i = 7;
		cout << i << endl; 
	} 
	cout << i << endl;
	return 0;
}

对象的生存周期

  • 静态生存期:整个程序运行期间都存在,static修饰,未初始化默认为0
  • 动态生存期:结束于作用域尾
#include <iostream>
using namespace std;

int i = 0; //全局变量,文件作用域 
void other(){
	static int a = 1;  //静态局部变量 
	int c = 10;       //局部变量,动态生存期
	a += 2;
	i +=32;
	c +=5; 
	cout << "i: " << i << " a: " << a << " c: " << c << endl;
}

int main(){
	other();
	other();
	return 0;
}

类的静态成员

类的静态数据成员

  • static修饰,为该类的所有对象共享,具有静态生存期
  • 必须在类外定义和初始化,用 :: 来指明所属的类

类的静态函数成员

  • 一般只用于处理类的静态数据成员,不处理具体某个对象的数据。
#include <iostream>
using namespace std;

class Point{
	public:
		Point(int x=0, int y=0):x(x), y(y){
			count++;
		}
		Point(const 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::showCount(); //可以直接调用,不需要通过对象调用 
	Point a(4, 5);
	cout << a.getX() << a.getY() << endl;
	a.showCount();     //也可以通过对象调用
	
	Point b(a);
	cout << b.getX() << b.getY() << endl;
	Point::showCount();
	return 0;
}

友元

  • 友元模块可以访问到另一个模块中被隐藏的信息
  • 关键字 friend 修饰,可以访问private 和 protected成员
  • 在封装和快速性达到平衡

友元函数

#include <iostream>
#include <cmath>
using namespace std;

class Point{
	public:
		Point(int x=0, int y=0):x(x), y(y){
		}
		int getX(){return x;}
		int getY(){return y;} 
		friend double dist(const Point& a, const Point& b){   //友元函数 
			double x = a.x - b.x;  
			double y = a.y - b.y;
			return static_cast<float>(sqrt(x*x+y*y));
		} 
	private:
		int x, y;
}; 

int main(){
	Point p1(1, 5), p2(1,2);
	cout << dist(p1, p2) << endl;
	return 0;
}

友元类

  • 若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员
  • 友元关系是单向的

image-20200711150004819

共享数据的保护

  • 关键字 const 修饰

常对象

const Point a(3, 4);  //a是常对象,不能被更新

常成员函数

  • 返回类型 函数名(参数表) const

  • 不更新对象的数据成员

  • 通过常对象只能调用它的常成员函数,非常对象也可以调用它的常成员函数

  • 可以用来区分重载函数

#include <iostream>
#include <cmath>
using namespace std;

class Point{
	public:
		Point(int x=0, int y=0):x(x), y(y){
		}
		int getX(){return x;}
		int getY(){return y;} 
		void print();
		void print() const; //常成员函数 
	private:
		int x, y;
}; 

void Point::print(){
	cout << x << y << endl;
}

void Point::print() const{
	cout << x << y << endl;
}

int main(){
	Point p1(1, 5);
	p1.print();  //调用void print() 
	
	const Point p2(2, 4);
	p2.print();  //调用void print() const 
	return 0;
}

常数据成员

  • 只能在初始化的时候赋值,其他时候不可以改变其值
#include <iostream>
#include <cmath>
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 a1(100), a2(0);
	a1.print();
	a2.print(); 
	return 0;
}

常引用

  • 不能通过常引用修改原来的值
  • 非常安全

多文件结构与预编译命令

多文件结构

  • 类声明文件(.h文件)
  • 类实现文件(.cpp文件)
  • 类的使用文件(main所在的.cpp文件)

编译与链接

image-20200711160124414

//类的定义
class Point{
	public:
		Point(int x=0, int y=0):x(x), y(y){
			count++;
		}
		Point(const Point& p); //复制构造函数
		~Point(){       //析构函数 
			count--;
		}
		int getX() const{return x;}
		int getY() const{return y;} 
		static void showCount();  //静态函数成员
	private:
		int x, y;
		static int count;   //静态数据成员声明 
};

//类的实现
#include "point.h"
#include <iostream>
using namespace std;

int Point::count = 0;  //初始化静态数据成员

Point::Point(const Point& p):x(p.x), y(p.y){
	count++;
} 

void Point::showCount(){
	cout << "Object count: " << count << endl;
}

//主函数文件
#include <iostream>
#include "point.h" 
using namespace std;

int main(){
	Point a(4, 5);
	cout << a.getX() << a.getY() << endl;
	Point::showCount();
	
	Point b(a);
	cout << b.getX() << b.getY() << endl;
	b.showCount();
	return 0;
}

外部变量与函数

  • 外部变量:文件作用域中定义的变量,默认情况下为外部变量;若需在其他文件中使用,则使用extern关键字修饰

  • 外部函数:类定义之外的函数具有文件作用域,若需在其他文件使用只需extern声明一下即可

  • 在匿名空间中定义的变量和函数不会暴露给其他单元

    namespace {
    	int n;
    	void f(){
    		n++;
    	}
    }
    
    

编译预处理命令

  • include:将一个源文件插入到当前源文件中该点处

    • 自定义的.h文件在include时用 " ",会现在当前工作目录找,然后再到系统目录找;而系统.h文件使用 < >,直接到系统目录找
  • define:宏定义指令

    • 定义符号常量,可以用const取代
    • 定义带参数宏,可以用内联函数取代
  • undef:删除#define定义的宏

  • if 和 #endif:选择编译

    #if 常量表达式
    	程序正文1   //当常量表达式非零时编译
    #else
    	程序正文2
    #endif
    
    
  • ifdef 和ifndef:选择编译,一般在头文件中使用;避免多次编译

    #ifdef 标志符
    	程序段1   //当标识符未被定义过则编译
    #else
    	程序段2
    #endif#
    
    
posted @ 2020-07-16 19:13  happy_fan  阅读(278)  评论(0编辑  收藏  举报