c++ ch5数据共享与保护

作用域

从小到大:
函数原型作用域:作用域是形参表中;
(块)局部作用域:初始化的函数体{}之内;
在这里插入图片描述
类作用域:类中可用,类外public可访问类名.对象名。静态成员的引用访问&非静态成员的指针访问;
文件作用域/静态作用域:起始于声明点,整个文件有效。

可见性

内层域向外层域,可见才能引用。
内外层标识符如果重名了,就会导致外层在内层中不可见。如上段程序输出 1 5,因为同名的局部作用域在第一个cout时被覆盖不可见。

int i;//文件
int main(){
i=5;//为全局变量赋值
{
int i=1;//局部
cout<<i<<endl;
}
cout<<i<<endl;
return 0;
}
生存期与类的静态

静态生存期:可在声明时加上static,生存期与程序运行期一致,全局变量天生具有静态生存期;
动态生存期:起始于声明,结束在作用域结束。

整个类的共有,但不是类内,用static。静态数据成员的声明是类内,而定义与初始化在类外——数据类型 类名::对象名的初始化;
例5.5静态对象成员

#include<iostream>
using namespace std;

class Point {
private:
	int x, y;
	static int count;
public:
	void getpoint() { cout << "(" << x << "," << y << ")"<<endl; }
	void showcount() { cout << count << endl; }
	Point(int a, int b);//构造函数声明
	Point(Point& p) { x = p.x; y = p.y; count++}//复制构造函数
	~Point() { count--; }//析构,数量下降(反构造)
};//class{}后要加分号

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

int Point::count = 0;//用类名来限定,初始化静态数据成员
int main() {
	Point  A(4, 5);
	A.getpoint();
	A.showcount();
	Point  b(A);
	b.getpoint();
	b.showcount();
	return 0;
}

缺陷:但是当没有点时,这时不会出count=0。
例5.6静态函数成员

#include <iostream>

using namespace std;

class Point {    

public:      

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

                        

       Point(Point &p) {    //复制构造函数,&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,其构造函数回使count增1

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

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

 
       Point b(a); //定义对象b,其构造函数回使count增1

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

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

 

       return 0;

}

比起5.5,
1.由于函数改成静态函数,类中原本与静态数据成员有关的函数写成了 static void showCount() { }。
2.且主函数输出由对象名.函数写成了类名.函数,这个类的这个函数已经固定。

友元friend

可访问类的私有成元,增加灵活性,但是存在违背完整性,是封装与隐藏的机制。少使用。
友元函数:访问中必须有对象名。
class中函数加friend声明。
用对象做参数时,使用引用可以提高效率。&p但是引用是双向传递,可能会反向修改。

友元类:一个类的友元类中的成员函数都是这个类的友元函数

class A{
friend class B;//S对B开放权限,B中可以对A修改了
public:
private:
};

但是类的友元关系是单向的,上述的A并不能修改B。B是A的友元,但是A类不是B类的友元。

共享数据的保护

常对象const定义时就要初始化。

class A{};
A const a(4,5);//const写在数据类型说明符后

常引用:被引用的对象不能被更新,不想双向传递。只读。高效。如const Point &p
常数组ch6
常指针ch6
常函数:处理常对象。不更新对象

int prr(int a,Point b)const;

不打算改变对象状态的函数都可以加上const做出承诺。之后如果加上了常对象,会更加方便。

例5.7-5.9自己写一遍

//5-7
#include<iostream>
using namespace std;

class Pom {
private:
	int a, b;
public:
	void show(class Pom) { cout << a << " " << b << endl; }
	void print(class Pom)const {  cout << a << " " << b << endl; }
	Pom(int a, int b) :a(a), b(b) {}

};
/*
Pom::Pom(Pom & x) {
	a = x.a;
	b = x.b;
}
*/


int main() {
	int a, b;
	Pom xx(6,8);
	xx.print(xx);
	xx.show(xx);
	return 0;
}

静态常数据成员

//5.8
#include<iostream>
using namespace std;

class Pom {
private:
	int a, b;
	static const int  c;//类内声明,const在前啊,且作为静态数据static
public:
	void show(class Pom) { cout << a << " " << b << " " << c<< endl; }
	void print(class Pom)const {  cout << a << " " << b << " " << c << endl; }
	Pom(int a, int b) ;

};
const int Pom::c = 10;//类外定义与初始化
	Pom::Pom(int a, int b) :a(a), b(b) {};
int main(){
	Pom aa(44, 6);
	aa.show(aa);
    aa.print(aa);
	return 0;
}

常引用:高效的同时保持了实参的安全性

 Point dist(const Point &p){

}

**static_cast<类型>**是一个c++运算符,功能是把一个表达式转换为某种类型,但没有运行时类型检查来保证转换的安全性。
构造函数与复制构造函数的语法还是要多写

多文件&编译预处理

类声明与定义 .h
类实现函数 .cpp
类的使用文件(main所在) .cpp
2.
“ .h"先从当前文件夹查找;
< >先从自带函数库查找。
3.标准库:
输入输出类
容器类与抽象数据类型
存储管理类
算法
错误处理
运行环境支持
4.
define/ifdef/else/ifndef/endif

实验五

用编译预处理

#ifndef CLIENT_H_
#define CLIENT_H_
....
#endif

静态数据成员的引用,需要**类名:😗*来修饰。

#include<iostream>
//#include"client.h"

using namespace std;

class client {
public:
	static void change(char name);
	client(char t);
	static int getnumber();
	client(const client& a);
private:
	static char servername;
	static int servernumber;

};

void client::change(char name) {
	client::servername = name;
	//client::servernumber++;
}

client::client(char t) { client::servername = t; client::servernumber++; }

client::client(const client& a) {
	client::servername = a.servername;
	client::servernumber++;
}

int client::getnumber() {
	cout << client::servernumber << endl;
	//return client::servernumber;
	return 0;
}

int client::servernumber = 0;
char client::servername = 'a';
int main(){
	char m = 'm';
	client x(m);
	x.change('n');
	x.getnumber();
	client y(m);
	y.change('s');
	y.getnumber();
	return 0;
	}

注:
如果拆分成多文件项目的话,如类声明.h+类定义.cpp+main.cpp,要将文件加进右侧解决方案资源管理器的项目解决方案源文件中,否则会报错:存在无法解析的外部符号错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值