*数据的共享与保护:
* 1.作用域:
* 作用域是一个标识符在程序正文中有效的区域。C++中标识符的作用域有函数原型作用域、局部作用域(块作用域)、类作用域和命名空间作用域。
* (1).函数原型作用域:
* 函数原型作用域是C++中最小的作用域,在函数原型中一定要包含形参的类型说明。在函数原型声明时形式参数的作用范围就是函数原型的作用域。如:double area(double radius);标识符radius的作用范围就在函数area形参列表的括号之间。
* 由于在函数原型的形参列表中起作用的只是形参类型,标识符并不起作用,因此在程序中是允许省去的,但是为了程序的可读性,通常还是要在函数原型声明时给出形参标识符。
* (2).局部作用域:
* 函数形参列表中形参的作用域,从形参列表中的声明处开始,到整个函数体结束为止;函数体内声明的变量,其作用域从声明处开始,一直到声明所在块结束的大括号为止;具有局部作用域的变量也称为局部变量。
* (3).类作用域:
* 类可以看作是一组有名成员的集合,类x的成员m具有类作用域,对m的访问方式有3中:如果在x的成员函数中没有声明同名的局部作用域的标识符,那么在该函数内可以直接访问成员m;通过表达式x.m或者x::m。即程序中访问对象成员的最基本方法;通过ptr->m这样的表达式,其中ptr为指向x类的一个对象的指针。
* (4).命名空间作用域:
* 一个大型的程序通常有不同模块构成,不同的模块有可能有不同人员开发的。不同模块中的类和函数之间可能发生重名。命名空间就会消除这些错误。语法结构:
* namespace 命名空间名{
* //命名空间内的各种声明(函数声明、类声明、。。。);
* }
* 一个命名空间确定了一个命名空间作用域,凡是在该命名空间之内声明的、不属于前面所说各个作用域的标识符,都属于该命名空间作用域。在命名空间内部可以直接引用当前命名空间中声明的标识符,如果需要引用其他命名空间的标识符,需要使用下面语法:
* 命名空间::标识符
*
* namespace someNs{
* class SomeClass{...};
* };
* 如果要引用类名SomeClass或函数名SomeFunc,需要使用下面的方式:
* someNs::SomeClass obj;
* 有时,在标识符前面总使用这样的命名空间限定会显得过于冗长,为了解决这个问题,C++又提供了using 语句,using语句有两种:
* using 命名空间::标识符;
* using namespace 命名空间名;
* 命名空间也允许嵌套:
* namespace OuterNs{
* namespace InnerNs{
* class SomeClass{...};
* }
* }
* 引用其中的SomeClass类,需要使用OuterNs::InnerNs::SomeClass的语法;
* 此外,还有两种比较特殊的命名空间:
* 全局命名空间和匿名命名空间。全局命名空间是默认的命名空间,在显示声明的命名空间之外声明的标识符都在一个全局命名空间中,匿名命名空间是在一个需要显示声明的没有名字的命名空间。声明如下:
* namespace{
* 匿名命名空间内的各种声明(函数声明、类声明、...);
* }
* 具有命名空间作用域的变量又称为全局变量;
*
* 2.对象的生存期:
* (1).静态生存期:
* 如果对象的生存期与程序的运行期相同,则称它具有静态生存期;在命名空间作用域中声明的对象都是具有静态生存期的。如果在函数内部的局部作用域中声明具有静态生存期的对象,则要使用关键字static。如:static int i;
* 局部作用域中的静态变量的额特点是:它并不随着每次函数调用而产生副本,也不会随着函数返回而失效。也就是说当一个函数返回后,下一个再调用时,该变量还是上一次的值。即使发生递归调用也不会为该变量建立新的副本,该变量会在每次调用间共享。
* (2).动态生存期:
* 局部生存期对象诞生于声明点,结束声明所在的执行完毕之时。类成员对象也有自己的生存期。不用static修饰的成员对象其生存期都与它们所属对象的生存期保持一致。
*
* 3.类的静态成员:
* 在结构化程序设计中程序模块的基本单位是函数,因此模块间对内存中数据的共享是通过函数与函数之间的数据共享来实现的,其中包括两个途径:参数传递和全局变量。
* (1).静态数据成员:
* 如果某个属性为整个类所共有,不属于任何一个具体对象,则采用static关键字来声明一个静态成员。静态成员在每个类只有一个副本,由该类所有对象共同维护和使用,从而实现了同一类的不同对象之间的数据共享。类属性是描述类的所有对象共同特征的一个数据项,对于任何对象实例,它的属性值是相同的静态数据成员具有静态生存期。由于静态数据成员不属于任何一个对象,因此可以通过类名对它进行访问,一般用的语法是:
* 类名::标识符;
*
* (2).静态函数成员:
* 静态成员函数可以直接访问该类的静态数据和函数成员。而访问非静态成员,必须通过对象名。
*class A{
public:
static void f(A a);
private :
int x;
};
void A::f(A a){
cout<<x;// This is WRONG!
cout<<a.x;//之所以在静态成员函数中访问类的非静态成员需要指明对象是因为对静态成员函数的调用是没有目的对象的,因此不能像非静态成员函数那样隐含地通过目的对象访问类的非静态成员。

}
*
* 4.类的友元:
* 友元关系提供了不同类或对象的成员函数之间、类的成元函数与一般函数之间的关系进行数据共享的机制。通俗的说,就是一个类主动声明哪些其他类或函数是它的友员,今儿给它们提供对本类的访问特许。通过友元关系一个普通函数或者类的成员函数可以访问封装与另一个类中的数据。从一定程度上讲,与友元关系是对数据隐蔽和封装的破坏。
* 在一个类中可以利用关键字friend将其他函数或类生命为友元。如果友元是一般函数或类的成员函数,称为友元函数;如果友元是一个类,则称为友元类,友元类的所有函数都自动成为友元函数。
* (1).友元函数在类中用关键词friend修饰的非成员函数。友元函数可以使一个普通函数也可以是其他类的成员函数。
* #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 float dist(Point &p1,Point &p2);//友元函数声明;
private:
int x,y;
};
//友元函数dist的定义
float dist(Point &p1,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(){
Point myP1(1,1),myP2(4,3);
cout<<"The distance is:";
cout<<dist(myP1,myP2)<<endl;
return 0;
}
* 在Point类中只声明友元函数的原型,友元函数dist的定义在类外,可以看出友元函数通过对象名直接访问了Point类的x和y属性。
*
* (2).友元类:
* 若类A为B类的友元类,则A类的所有成员函数都是B类的友元函数,都可以访问B类的私有和保护成员。
* class B{
* friend class A;//声明A为B的友元类。
* };
* 声明友元类是建立在类与类之间的练习,实现类与类之间数据的共享的一种途径。
* #include <iostream>
using namespace std;
class A{
public:
void display(){cout<<x<<endl;}
int getX(){return x;}
friend class B;
private:
int x;};
class B{
public :
void set(int i);
void display();
private:
A a;
};
void B::set(int i){
a.x=i;//因为B是A的友元,所以在B的成员函数中可以访问A类的所有私有成员;
}
*
* 注:友元关系是不能传递的,B是A的友元,C是B的友元,如果没有声明C是A的友元就没有友元关系。友元关系是单向的,如果B是A的友元,B可以访问A的私有数据和保护数据,但A的成员函数不能访问B的私有和保护数据。友元关系是不能被继承的,如果B是A的友元,B的派生类不能自动的成为A的友元。
*
* 5.共享数据的保护:
* (1).常对象:
* 常对象的数据成员值在对象的整个生存期内不能被改变。也就是说常对象必须进行初始化,而且不能被更新。
* const 类型说明符 对象名;
* class A{
public:
A(int i,int j):x(i),y(j){};
private :
int x,y;
};
const A a(3,4);//a是常对象,不能被更新。
*
* (2).const 修饰的类成员:
* 常用成员函数:使用const关键字修饰的函数为常成员函数,声明格式:
* 类型说明符 函数名(参数表) const;
* 如果将一个对象设置为常对象,则通过该常对象只能调用它的常成员函数,而不能调用其他成员函数;
* const关键字可以用于对重载函数的区分,void print(); void print() const;
* 常数据成员:使用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 a(100),a2(3);
a.print();
a2.print();
return 0;
}
*
* 常引用:
* 如果在申明引用时用const修饰,被申明的引用就是常引用,常引用所引用的对象不能被更新。如果常引用作为形参,便不会发生对实参的更改。
* const 类型说明符 &引用名;
* 非const的引用只能绑定到普通的对象,而不能绑定到常对象,但常引用可以绑定到常对象。一个常引用,无论是绑定到一个普通对象还是常对象,通过该引用访问该对象时,只能把该对象当作常对象。这意味着对于基本数据类型的引用,则不能为数据赋值,对于类类型的引用,则不能修改它的数据成员,也不能调用它的非const的成员函数。
*
* 6.C++多文件结构和编译预处理命令:
* (1).C++的一般结构:
* 在多个文件结构中,#include指令的作用是将指定的文件嵌入到当前源文件中,这个被嵌入的文件可以使cpp文件,也可以是h文件。指令include有两种写法:#include<文件名>表示按照标准方式搜索要嵌入的文件,该文件位于编译器环境的include子目录下,一般嵌入系统提供的标准文件时采用的方式。另一种就是#include"文件名"表示首先在当前目录下搜索要嵌入 的文件,如果没有再按照标准方式搜索。
* (2).外部变量:
* 外部变量可以在源文件中可以使用,还可以被其他文件使用。 命名空间作用域中定义的变量,默认情况下都是外部变量,但在其他文件中如果需要使用这一变量,需要用extern关键字加以声明。
* (3).外部函数:
* 在所有类之外声明的函数(非成员函数),都是具有命名空间作用域的,如果没有特殊说明,这样的函数都可以在不同的编译单元中被调用,只要在调用之前进行引用性声明。也可以在声明函数原型或定义函数时用extern修饰。
*
* 7.标准C++库:
* C++的库中保留了大部分C语言系统函数和另外预定义的模板和类。使用标准C++库时,还需要加入下面一条语句来将指定命名空间中的名称引入到当前作用域中:
* using namespace std;
* 如果不使用using namespace std,就需要在使用std命名空间中的标识符时冠以命名空间名std::;
* (1).编译预处理:
* #include指令:
* 文件包含指令,起作用是将另一个源文件嵌入到当前源文件中该点处,通常用#include指令来嵌入头文件。
* #define和#undef指令:
* #define曾经在C程序中被广泛使用,但#define能完成的一些功能,能够被C++引入的一些语言特性很好的代替。在C语言中用#define来定义符号常量,如:#define PI 3.14;在C++中也同样定义符号常量,但是更好地方法是在类型说明语句中用const修饰。#undef的作用是删除由#define定义的宏,使之不再起作用。
* 条件编译指令:
* #if 常量表达式 或 #ifdef 标识符 或 #ifndef 标识符
* 程序段;
* #elif
* 程序段;
* #else
* 程序段;
* #endif
* */

转载于:https://www.cnblogs.com/feiruo/p/4678846.html

我的C++笔记(数据的共享与保护)相关推荐

  1. 【学习笔记】C++语言程序设计(郑莉):数据的共享与保护

    [学习笔记]C++语言程序设计(郑莉):数据的共享与保护 1. 标识符的作用域与可见性 1.1 作用域 1.1.1 函数原型作用域 1.1.2 局部作用域 1.1.3 类作用域 1.1.4 命名空间作 ...

  2. 第5章 数据的共享与保护

    本专栏为C++学习笔记,参考书籍为:C++语言程序设计 第五版 -清华大学出版社- 郑莉 B站视频:https://space.bilibili.com/702528832/video PPT与代码已 ...

  3. Part5 数据的共享与保护 5.4类的友元5.5共享数据的保护

    友元是C++提供的一种破坏数据封装和数据隐藏的机制. 通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息. 可以使用友元函数和友元类. 为了确保数据的完整性,及数据封 ...

  4. Homework7_ch5 数据的共享与保护(2)——friend

    1. 友元函数设计 1.1 程序描述 模拟电力公司统计用户用电量.请设计一个类FamliyElecPower描述每户人家一年的用电情况,一年的12个月的每月电量都要记录.设计函数CalTotalEPo ...

  5. 开放科学背景下的科学数据开放共享:国家青藏高原科学数据中心的实践

    开放科学背景下的科学数据开放共享:国家青藏高原科学数据中心的实践 潘小多1,2, 李新1,2, 冉有华3, 郭学军2 1 中国科学院青藏高原研究所国家青藏高原科学数据中心,北京 100101 2 中国 ...

  6. [PyTorch笔记]数据操作

    [动手学深度学习PyTorch笔记]--数据操作 1 引言 2 预备知识 2.1 数据操作 2.1.1 入门 2.1.2 运算符 2.1.3 广播机制 2.1.4 索引和切片 2.1.5 节省内存 2 ...

  7. Docker 入门系列(4)- Docker 数据管理(挂载目录、挂载文件、数据卷挂载、数据卷共享、数据卷删除、数据卷容器备份和恢复)

    基于底层存储实现,Docker 提供了三种适用于不同场景的文件系统挂载方式:Bind Mount.Volume 和 Tmpfs Mount. Bind Mount 能够直接将宿主操作系统中的目录和文件 ...

  8. 【8.23更新--技术干货全家桶】大数据计算技术共享计划 — MaxCompute技术公开课第二季...

    2018年5月-6月 MaxCompute 开启大数据计算技术共享计划技术公开课第一季,有超过1500名用户以及大数据爱好者参与到直播学习中来.7月,我们又开启第二季直播,5次大数据技术直播,有近60 ...

  9. 支付宝人脸数据被共享?李开复道歉

    9月12日消息,今天,有媒体报道创新工场董事长兼CEO李开复在HICOOL全球创业者峰会上表示,曾在早期帮助旷视科技公司找了包括美图和蚂蚁金服等合作伙伴,让他们拿到了大量的人脸数据,并在随后的摸索过程 ...

最新文章

  1. 关于Python爬虫原理和数据抓取1.1
  2. 不要假装很努力,因为结果不会陪你演戏
  3. Solr -- Solr Facet 1
  4. linux开放端口_Linux系统通过firewall限制或开放IP及端口 - 北方客888
  5. Flex4与WebService通信
  6. php实现附件上传下载,PHP实现文件上传与下载
  7. 管理你的代码——Git学习(一)
  8. 两种方法动态获得ABAP类的class attribute的值
  9. SharePoint 2010 中的BCS身份验证模式
  10. 判断输入的整数是否为素数_C语言 | 判断是否素数
  11. 构建Docker镜像指南,含实战案例
  12. 小熊的人生回忆(一)
  13. MTK 驱动开发(43)---GPS问题分类--MTK ALPS GPS的特殊知识
  14. YFI与Curve合作项目初始支持6种算法稳定币
  15. Keras源码下载记录
  16. 普通函数和Generator函数递归获取嵌套数组的最大值
  17. native2ascii命令用法详解
  18. java IO流:字节流、字符流
  19. 永久关闭“WPS热点”的显示_我是亲民_新浪博客
  20. 野指针?悬空指针? 一文带你搞懂!

热门文章

  1. 动态规划和分治法的区别
  2. 软件工程与软件测试基础知识_这是我在软件工程工作九个月中学到的知识
  3. 卸载linux系统装win,如何在计算机上删除 Linux 并安装 Windows
  4. python库引用的3种方式比较
  5. 坦克世界服务器未响应怎么解决,华硕笔记本老是程序未响应怎么处理
  6. java程序员入门先学什么开发者工具
  7. 苏宁零售云 App 稳定保障实践
  8. super的用法(带了解)
  9. linux学习笔记一
  10. 第一本的java 的小总结