数据域封装
先放一段之前的类定义代码。
#ifndef CIRCLE_H #define CIRCLE_H class Circle { public: //圆的半径 double radius; //无参构造函数 Circle(); //有参构造函数 Circle(double); //获取圆的面积 double getArea(); }; #endif
之前我们把所有的数据域和函数都放在了public之后。public的意思是公开的,也就是说,谁都可以访问这些数据和函数。
比如想要修改圆一个圆对象c1的半径,那么可以通过直接访问radius来修改
c1.radius = 2;
但是这样的风格并不好。具体表现在:
- 数据可能被搞乱。假如一个函数要使用类的一个属性。但是这个不被封装的属性可以被修改。这样可能会导致函数执行出不同的结果。
- 不易于维护。圆的半径一定是大于0的,但是如果数据不被封装,可以直接修改的话,我们就无法满足这个条件。
我们应该把我们的数据封装起来,而函数则一般不封装。
代表封装的关键字是private(私有的),做法同public类似。私有数据或函数只有在类内部可以访问,如果这时候再直接访问,编译器会报错。见下面的代码:
#ifndef CIRCLE_H #define CIRCLE_H class Circle { private: //圆的半径 double radius; public: //无参构造函数 Circle(); //有参构造函数 Circle(double); //获取圆的面积 double getArea(); //获取圆的半径 double getRadius(); //设置圆的半径,同时判断是否大于0 void setRadius(double newRadius); }; #endif
在上面的代码中,我们把数据半径封装,而且提供了getter和setter方法,也就是getRadius()和setRadius(double newRadius)。这两个方法分别负责获取和修改数据,而且命名方式一般都是getXxx()和setXxx(),用首字母大写来区分两个单词。
getter方法就像是一个访问器,而setter则像是一个更改器。
并不是说所有的数据都需要getter和setter方法,这要视情况而定。
变量作用域
一个程序的变量大体可分为两种类型:全局变量,局部变量。
局部变量是在函数内作定义说明的,其作用域仅限于函数内,离开该函数后再使用这种变量编译器会报错。
全局变量是在函数外部定义的变量。它不属于哪一个函数,它属于一个源程序文件,其作用域是整个源程序。
关于变量作用域,可以参考这篇博客:
类中的变量也符合这些规则。
特别注意的是,如果一个数据域或者函数被声明为static(即静态数据或函数),则这个数据或函数不属于某个具体的对象实例,而是属于这个类。因此,所有的对象的static数据都是一样的。