类和对象(2)—— 类的封装和访问控制
1、从struct说起
当单一变量无法完成描述需求的时候,结构体类型解决了这一问题。可以将多个类型打包成一体,形成新的类型。这是 c 语言中封装的概念。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; struct Data { int year; int month; int day; }; void init(Data &d) { cout << "year,mouth,day:" << endl; cin >> d.year >> d.month >> d.day; } void print(Data &d) { cout << "year:mouth:day:" << endl; cout << d.year<<":" << d.month << ":" << d.day << endl; } bool isLeapYear(Data &d) { if ((d.year % 4 == 0 && d.year != 0) || d.year % 400 == 0) return true; else return false; } int main(void) { Data d; init(d); print(d); if (isLeapYear(d)) cout << "leap year" << endl; else cout << "not leap year" << endl; return 0; }
对C语言中结构体的操作,都是通过外部函数来实现的。比如
void init(Data &d) void print(Data &d) bool isLeapYear(Data &d)
2、封装的访问属性
- struct 中所有行为和属性都是 public 的(默认)。C++中的 class 可以指定行为和属性的访问方式。
- 封装,可以达到对内开放数据、对外屏蔽数据、对外提供接口,达到了信息隐蔽的功能。
- 比如我们用 struct 封装的类,即知其接口,又可以直接访问其内部数据,这样却没有达到信息隐蔽的功效。而 class 则提供了这样的功能,屏蔽内部数据,对外开放接口。
3、用class去封装带行为的类
class 封装的本质,在于将数据和行为,绑定在一起然后能过对象来完成操作。
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Data { //一个类的内部,默认的访问控制权限是private public: void init() { cout << "year,mouth,day:" << endl; cin >> year >> month >> day; } void print() { cout << "year:mouth:day:" << endl; cout << year << ":" << month << ":" << day << endl; } bool isLeapYear() { if ((year % 4 == 0 && year != 0) || year % 400 == 0) return true; else return false; } int get_year() { return year; } void set_year(int new_year) { year = new_year; } private: int year; int month; int day; }; int main(void) { Data d; d.init(); d.print(); if (d.isLeapYear()) cout << "leap year" << endl; else cout << "not leap year" << endl; //getter,setter cout << d.get_year() << endl; d.set_year(2018); cout << d.get_year() << endl; return 0; } //C++中结构体和类的功能是一样的,在C++中将结构体升级了,结构体的方式就是一个类, //区别是默认的访问控制权限是不同的, //结构体struct默认为public,类class默认为private; //结构体没有成员方法,只能通过函数指针解决问题;
或者写成:
#define _CRT_SECURE_NO_WARNINGS #include <iostream> using namespace std; class Data { //一个类的内部,默认的访问控制权限是private public: void init(); void print(); bool isLeapYear(); int get_year(); void set_year(int new_year); private: int year; int month; int day; }; void Data::init() { cout << "year,mouth,day:" << endl; cin >> year >> month >> day; } void Data::print() { cout << "year:mouth:day:" << endl; cout << year << ":" << month << ":" << day << endl; } bool Data::isLeapYear() { if ((year % 4 == 0 && year != 0) || year % 400 == 0) return true; else return false; } int Data::get_year() { return year; } void Data::set_year(int new_year) { year = new_year; } int main(void) { Data d; d.init(); d.print(); if (d.isLeapYear()) cout << "leap year" << endl; else cout << "not leap year" << endl; //getter,setter cout << d.get_year() << endl; d.set_year(2018); cout << d.get_year() << endl; return 0; }
- Data 类 访问自己的成员,可以不需要传引用的方式;
- 封装有2层含义(把属性和方法进行封装 对属性和方法进行访问控制);
- Public修饰成员变量和成员函数可以在类的内部和类的外部被访问;
- private修饰成员变量和成员函数只能在类的内部被访问。
struct和class关键字区别:
在用struct定义类时,所有成员的默认属性为public;
在用class定义类时,所有成员的默认属性为private。