C/C++基础知识总结——数据的共享与保护
1. 标识符的作用域与可见性
1.1 作用域
标识符的作用域包括:函数原型作用域、局部作用域、类作用域、命名空间作用域
(1) 函数原型作用域:函数的参与的作用域就是从函数的开始到结束
(2) 局部作用域:
void fun(int a) { int b = a; cin>>b; if(b>0) { int c; //c的作用域 b的作用域 a的作用域 ... } }
(3) 类作用域
类X中有成员m,m的类作用域的三种表现
① 如果X的成员函数中没有声明同名的局部作用域标识符,那么在该函数内可以直接访问成员m。
② 通过表达式x.m或X::m。其中X::m的访问可以访问类X的静态数据
③ 通过x->m。指针
(4) 命名空间作用域(详细请参考:./命名空间详解)
① 命名空间作用域是对标识符的名称本地化,避免命名冲突。
② 定义命名空间:
namespace myNamespace { int i; class myClass { int a; } }
③ 使用命名空间方法:
A:
myNamespace::i = 0; myNamespace::myClass obj; obj.a = 1;//这里不用写myNamespace::myClass了
B:
using namespace myNamespace; i = 0; //就不用写myNamespace::i了,myNamespace里所有都暴露了
④ 命名空间可以嵌套
⑤ 静态变量作用域为本文件内。生存期和程序一样
⑥ 具有命名空间作用域的变量也成为全局变量
using namespace myNamespace; i = 0; //就不用写myNamespace::i了,myNamespace里所有都暴露了
2. 对象生存期
2.1 静态生存期
(1) 静态生存期与程序运行期相同。
(2) 命名空间作用域中声明的对象都具有静态生存期
(3) 如果在函数内部的局部作用域中声明的话需要用static
(4) 静态作用域中的静态变量特点是:不会随着函数的每次调用而产生一个副本
2.2 动态生存期
(1) 在局部声明的也叫局部生存期,诞生于声明点,结束于声明所在的块执行完毕
3. 类的静态数据成员
3.1 类的静态数据成员不属于某个类的对象,而属于这个类,采用static关键字声明。静态成员在每个类中都只有一个副本,由所有的对象共同维护和使用,实现了一个类不同对象之间的共享。用法: 类名::标识符
3.2 静态数据成员具有静态生存期。
3.3 用法:在类内部声明,在类的外部定义,如:
class point{ private: static int count;//声明 }; int point::count = 0;//定义
3.4 静态函数成员
(1) 也被一个类的各个对象共有
(2) 调用方式:
① 类名::函数名(推荐)
② 对象名.函数名
(3) 静态成员函数可以直接访问该类的静态数据和成员函数。而访问非静态成员,必须通过对象名
class A{ public: static void f(A a); private: int x; static int y; }; void A::f(A a) { cout<<x; //错误 cout<<a.x;//正确,但不推荐 cout<<y;//正确 }
4. 类的友元
友元关系提供了不同类或对象的成员函数等的数据共享机制。友元就是声明哪些类或者函数是自己的朋友,并且提供这些函数访问自己的数据的权利。
4.1 友元函数
(1) 友元函数是在类中用关键字friend修饰的非成员函数。这个函数可以是普通的函数也可以是其他类的成员函数。声明后,这个函数可以访问本类的私有和保护成员。
(2) 用法:
class point{ private: int x, y; public: friend float dist(point &p1, point &p2);//声明 } float dist(point &p1, point &p2){ p1.x + p2.x;//可以直接使用私有成员 }
4.2 友元类
(1) 如果A类为B类的友元类,则A的所有成员函数都可以访问B的所有成员。
(2) 用法:
class B { private: int x; friend class A; }; class A { void function(B &b){ cout<<b.x<<endl;//可以直接访问 }
(3) 注意:
① 友元关系不能传递
② 友元关系是单向的
③ 友元关系是不能继承的
5. 共享数据的保护
5.1 常对象
(1) 常对象必须进行初始化,并且不能被更新。
(2) 用法:
const 类型说明符 对象名
5.2 用const修饰的类成员
(1) 常成员函数
① 用法:
类型说明符 函数名(参数) const;
class A{ void function() const; } void A::function() const{ ... }
(2) 常数据成员
① 类的const对象只能用初始化参数列表进行初始化
5.3 常引用
(1) 用法:
const 类型说明符 &引用名
(2) 非const引用只能绑定到普通对象,而不能绑定到常对象,但常引用既可以绑定到常引用又能绑定到普通引用。但是绑定到普通引用的时候,在用的时候不能对这个普通对象进行修改。对于类类型的普通对象常引用,既不能修改数据成员,又不能调用它的非const成员函数。
(3) 对于在函数中无需改变其值的参数,不宜使用普通引用的方式传递,因为那会使得常对象无法被传入,采用值传递的方式或者传递引用可以解决这个问题,但是值传递有时比较慢,所以推荐采用常引用传递。
作者:viczzx 出处:http://www.cnblogs.com/zixuan-zhang 欢迎转载,也请保留这段声明。谢谢!