6.类的封装性
6.1初始类
计算机语言中有2个重要概念:数据、算法。过程化编程强调算法,对象化编程强调数据。同类型数据存放在数组中,不同类型数据存放在结构体中,若要把不同类型的数据和对数据的处理算法放在一起,这就引申出了类。
在类中不仅可以存放不同类型的数据,还可以存放函数,这样就把数据和算法统一起来管理。类中的数据称为数据成员,类中的函数称为成员函数。类和结构体一样,其结尾需要使用分号来结束定义。为了帮助识别类,程序员在类的书写上都遵循一个约定,即类名第一个字母大写(也可以不大写)。
类的3大特性:封装性、继承性、抽象性,这一节主要讲封装性。
#include <iostream>
using namespace std;
class Student {
public:
enum class school { primary_school, middle_school, collge }; //小学、中学、大学
const char* name; //姓名
int age; //年龄
school sch; //学校
const char* curriculum; //课程
int achievement; //成绩
public:
void printinfo(void)
{
cout << "学生姓名:" << name << endl;
cout << "年龄:" << age << endl;
switch (int(sch))
{
case 0:
cout << "学校:" << "primary_school" << endl;
break;
case 1:
cout << "学校:" << "middle_school" << endl;
break;
case 2:
cout << "学校:" << "collge" << endl;
break;
default:
cout << "学校:" << "..." << endl;
}
cout << "课程:" << curriculum << endl;
cout << "成绩:" << achievement << endl;
}
}; //需要使用分号结尾
int main(int argc, char **argv) {
Student stu1;
stu1.name = "zhangsan";
stu1.age = 13;
stu1.sch = Student::school::primary_school;
stu1.curriculum = "English";
stu1.achievement = 80;
stu1.printinfo();
return 0;
}
运行结果:
学生姓名:zhangsan
年龄:13
学校:primary_school
课程:English
成绩:80
代码中定义了新的数据类型:Student类,在main()函数中,实例化对象是stu1(stu1称为对象,在结构体中是变量),数据成员:name、age、sch、curriculum、achievement;成员函数:void printinfo(void)。在Student类中,数据成员和成员函数的访问权限都是public,若不写public,则类默认访问权限是private。
6.2类的访问控制
对类中的数据和函数(算法)进行访问,需要对其访问权限进行控制,这就是类的访问控制。在类中,对象的访问有3种权限:public、protected、private。
public表示类的公有成员,类中定义的函数可以访问,类外定义的函数也可以访问。protected表示类的保护成员,类中定义的函数可以访问,派生类中定义的函数可以访问,类外的函数不可以访问。private表示类的私有成员,类中定义的函数可以访问,派生类和类外定义的函数不可以访问。派生类会在类的继承性那一章进行解释,这一章主要介绍public和private。
在代码中,通常把数据放在private中,将函数放在public中,这样将数据进行隐藏,使用者只需要看到成员函数即可(接口)。将数据存放在类私有成员中进行隐藏,这就是类的封装性。
#include <iostream>
using namespace std;
enum class school { primary_school, middle_school, collge }; //小学、中学、大学
class Student {
private:
const char* name; //姓名
int age; //年龄
school sch; //学校
const char* curriculum; //课程
int achievement; //成绩
public:
void init_student(const char * stu_name, int stu_age, school stu_sch, const char * stu_curriculum, int stu_achievement)
{
name = stu_name;
age = stu_age;
sch = stu_sch;
curriculum = stu_curriculum;
achievement = stu_achievement;
}
void printinfo(void)
{
cout << "学生姓名:" << name << endl;
cout << "年龄:" << age << endl;
switch (int(sch))
{
case 0:
cout << "学校:" << "primary_school" << endl;
break;
case 1:
cout << "学校:" << "middle_school" << endl;
break;
case 2:
cout << "学校:" << "collge" << endl;
break;
default:
cout << "学校:" << "..." << endl;
}
cout << "课程:" << curriculum << endl;
cout << "成绩:" << achievement << endl;
}
}; //需要使用分号结尾
int main(int argc, char **argv) {
Student stu1;
//stu1.name = "zhangsan";
//stu1.age = 13;
//stu1.sch = Student::school::primary_school;
//stu1.curriculum = "English";
//stu1.achievement = 80;
//stu1.printinfo();
stu1.init_student("zhansgan", 13, school::primary_school, "English", 80);
stu1.printinfo();
return 0;
}
这段代码是对上一段代码的优化,其运行结果相同。由于类中数据成员在main()中无法直接访问,因此在类中定义一个初始化函数init_student(),对类对象的数据成员进行初始化。
6.3 this指针
在前面的init_student()函数中,传入形参stu_name、stu_age、stu_sch、stu_curriculum、stu_achievement,为了让使用者更加明白形参的意思,能否直接用name、age、sch、curriculum、achievement来做为形参呢?可以的,为了区分形参中的name和类Student中数据成员name,C++引入了this指针。this->name表示类Student中数据成员name,这样2个name就区分开了。
实际上,this是一个指向对象本身的一个指针,从成员函数开始前构造,在成员函数结束时销毁;并且this指针只能在类的成员函数中使用。this指针还常用于在类的非静态成员函数中返回类对象本身的时候,直接使用return *this。
#include <iostream>
using namespace std;
enum class school { primary_school, middle_school, collge }; //小学、中学、大学
class Student {
private:
const char* name; //姓名
int age; //年龄
school sch; //学校
const char* curriculum; //课程
int achievement; //成绩
public:
void init_student(const char * name, int age, school sch