白话C++系列(8)-- 数据封装
2016-04-11 21:11 Keiven_LY 阅读(1243) 评论(0) 编辑 收藏 举报属性封装的艺术
数据的封装
下面看一个例子,例子中定义了一个学生的类,类中含有两个数据成员,一个是姓名,一个是年龄
上面的代码给人一种相当亲切,有一种似曾相识的感觉,那是因为之前我们一直都是这么用的,而且用的也很爽。但是,这样用是有问题的,最大的问题是它违背了面向对象的指导思想。
那么面向对象的基本思想是什么呢?
面向对象的核心就是以对象为中心,具体来说,就是要以谁做什么来表达程序的逻辑,体现在代码层面上,就是将所有的数据操作转换为成员函数的调用。换句话说,对象在程序中的所有行为都通过调用自己的函数来完成。
那么如何通过函数来封装数据成员呢?
接着继续看上面这个例子,这次我们把数据成员定义在private的下面,以年龄这个数据成员为例,我们定义两个成员函数,一个用于设置年龄的值,一个用于读取年龄的值
封装的好处
以上面Student的类为例,当我们还是用以前的老方法来访问数据成员,如果赋值时出现非法的情况,比如,给年龄数据成员赋值1000,显然是有问题的。但是如果通过数据的封装,就能很好的解决这个问题。
还是以上面Student的类为例,上面的封装只是简单的封装,如果我们对上面的成员函数setAge()做一下改变(如下),就会避免了上面非法输入的问题了。
接着以汽车(Car)为例来进一步说明封装的好处,如下
我们定义一个Car类,在这个类下面定义了一个private属性的数据成员,表示汽车轮子的个数,针对这个数据成员,我们不希望外界通过某个函数来改变它的值,我们只希望能读取它的值就ok了。我们称这种只能读取而不能设置的属性为只读属性。
代码实践
题目描述:
定义一个Student类,含有如下信息:
1 姓名:name
2 性别:gender
3 学分(只读):score
4 学习:study(用于获得学分)
#include <iostream> #include <stdlib.h> #include <string> using namespace std; /* **********数据的封装 定义一个Student类,含有如下信息: 1 姓名:name 2 性别:gender 3 学分(只读):score 4 学习:study(用于获得学分) /* ************************************/ class Student { public: void setName(string _name) { m_strName = _name; } string getName() { return m_strName; } void setGender(string _gender) { m_strGender = _gender; } string getGender() { return m_strGender; } int getScore() { return m_iScore; } void initScore() { m_iScore = 0; } void study(int _score) { m_iScore += _score; } private: string m_strName; string m_strGender; int m_iScore; }; int main() { Student stu; stu.initScore();//如果这里不进行初始化,m_iScore的值就不可控 stu.setName("Zhangsan"); stu.setGender("女"); stu.study(5);//学习一门学分为5分的课程 stu.study(3);//学习一门学分为3分的课程 cout<<stu.getName() <<" "<<stu.getGender() <<" "<<stu.getScore() <<endl; system("pause"); return 0; }
运行结果: