数据的共享和保护

对象的生存期

static类型的局部变量,生存期在整个程序,局部可见。

void example()
{
static a=1;
int b=2
}
当调用完example函数后,b消亡,a仍然存在;
再次调用该函数时,a值不会再次被赋值,仍保持之前数据;而b需要重新建立,重新赋值。

类的静态数据成员

1.用关键字static声明;

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

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

这个数据属于类的信息,比如统计教师群体中教师的总数,即这个类实例化了多少个对象。

class A{
static int num; //在类内声明
} int A::num=0; //在类外定义和初始化

类的静态函数成员

1.类外代码可以使用类名和作用域操作符来调用静态成员函数;

2.静态成员函数主要用于处理该类的静态数据成员,可以直接调用静态成员函数;

3.如果访问非静态成员,要通过对象来访问。

class A{
private:
static int num;
int a=1;
public:
static void shownum(){cout<< num << endl;} //2.
static int change(int a);//一个定义的例子;
}
int A::num=0;
int A::change(int a){
A::num=a; //静态数据成员的引用需要加 “类::”来修饰
} int main(){
A:shownum(); // 1.
}

类的友元

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

友元函数

在类声明中由关键字friend修饰说明的非成员函数,在它的函数体中能

够通过对象名访问 private 和 protected成员

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 &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;
}

友元类

friend声明是单向授权声明,类A是类B的友元,意味着类A获得了访问类B的私有成员的权限,但类B不能反向访问类A的私有成员;

此处的friend更像是一种"上级声明"
class A {
friend class B;
public:
void display() {cout << x << endl;}
private:
int x;
}; class B {
public:
void set(int i);
void display();
private:
A a; //B类中含有A类成员,正常来说是看不到封装的私有成员的
}; void B::set(int i) { a.x=i; } //因为是友元,所以可以通过对象名访问私有成员
void B::display() { a.display(); }
共享数据的保护
  • 对于既需要共享、又需要防止改变的数据应该声明为常类型(用const进行修饰);
  • 对于不改变对象状态的成员函数应该声明为常函数.

常类型

  • 常对象:必须进行初始化,不能被更新
    const 类名 对象名   const A a(1,2);
  • 常成员: 用const进行修饰的类成员:常数据成员和常函数成员
  • 常引用:被引用的对象不能被更新,既增加了效率又避免数据被篡改;常用作形参
const 类型说明符 &引用名  const int &p;const A &p;
  • 常数组:数组元素不能被更新(详见第6章)。
类型说明符 const 数组名[大小]...
  • 常指针:指向常量的指针(详见第6章)。

数组

处理无明显规律的大量同类型数据时,可以通过将其存入数组强制性添加一个次序信息,再结合循环语句,对其进行处理。

a[10]

数组名 a 是一个地址(指针)类型常量,对应数组首元素的内存地址,不能被赋值

数组名作函数参数

  • 形、实参数都应是数组名(实质上是地址),类型要一样,传送的是数组首地址;
  • 对形参数组的改变会直接影响到实参数组.
void rowSum(int a[][4], int nRow)
{
for (int i = 0; i < nRow; i++)
{
for(int j = 1; j < 4; j++)
a[i][0] += a[i][j];
} } int table[3][4] = {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}};
rowSum(table, 3);

对象数组

Point a[3];

实例化3个Point类的对象,调用3次构造和3次析构函数;

基于范围的for循环

  • 用来遍历容器类十分方便
  • c++11标准
double prices[5]={4.99, 2.33, 5.86, 6.42, 4.51};
for (double x : prices)
cout<<x<<std::endl;

最新文章

  1. Word2010如何恢复没有保存的文件
  2. 3分钟干货学会使用node-inspector调试NodeJS代码
  3. 通过broadcastreceiver 监听短信问题
  4. Spring 复习笔记01
  5. 用Jquery控制文本框只能输入数字和字母
  6. Client–server model
  7. Web端服务器推送技术原理分析及dwr框架简单的使用
  8. Python-Day15 JavaScript/DOM
  9. ERROR 2003 (HY000): Can&#39;t connect to MySQL server on &#39;localhost&#39; (10061)
  10. sql查询结果集根据指定条件排序的方法
  11. 【PostgreSQL】PostgreSQL语法
  12. magento模块的建立
  13. Java并发之AQS详解
  14. [TopCoder]棍子
  15. 学习笔记TF067:TensorFlow Serving、Flod、计算加速,机器学习评测体系,公开数据集
  16. Day17总结
  17. win7 64 位 + vs2015 + opencv3.2
  18. Spark练习代码
  19. C++树的插入和遍历(关于指针的指针,指针的引用的思考)
  20. (功能篇)回顾Bug管理系统Mantis优化改造经历

热门文章

  1. SCCM2007日志文件
  2. 如何在Code First、Database First和Model First之间选择
  3. mongodb的安装和启动
  4. [BZOJ 4010][HNOI 2015] 菜肴制作
  5. Directed Graphs
  6. GET POST 传值与接收案例
  7. nodejs中命令行中参数的获取和解析
  8. TensorFlow函数(二)tf.get_variable() 和 tf.Variable()
  9. 【Java123】Yaml格式
  10. I、Q信号是如何产生的,I、Q信号复用的作用