# C++的封装 # 1. 封装 ## 1.1 封装属性和行为 ① 封装是C++面向对象三大特性之一。 ② 封装的意义一: 1. 将属性和行为作为一个整体,表现生活中的事物。 2. 将属性和行为加以权限控制。 ```python #include using namespace std; const double PI = 3.14; //设计一个圆类,求圆的周长 //圆求周长的公式: 2 * PI * 半径 //class 代表设计一个类,类后面紧跟着的就是类名称 class Circle { //访问权限 //公共权限 public: //是冒号,不是分号 //属性 //半径 int m_r; //行为 //获取圆的周长 double calculateZC() { return 2 * PI * m_r; } }; int main() { //通过圆类 创建具体的圆(对象) //实例化 (通过一个类 创建一个对象的过程) Circle c1; //给圆对象 的属性进行赋值 c1.m_r = 10; // 2 * PI * 10 = 62.8 cout << "圆的周长为:" << c1.calculateZC() << endl; system("pause"); return 0; } ``` 运行结果: - 圆的周长为:62.8 ## 1.2 封装权限 ① 类在设计时,可以把属性和行为放在不同的权限下,加以控制。 ② 封装的意义二: 1. public 公共权限 2. protected 保护权限 3. private 私有权限 ```python #include using namespace std; //访问权限 //三种 //公共权限 public 类内可以访问成员 类外可以访问成员 //保护权限 protected 类内可以访问成员 类外不可以访问成员 子类可以访问父类中的保护内容 //私有权限 private 类内可以访问权限 类外不可以访问成员 子类不可以访问父类中的私有内容 class Person { //公共权限 public: string m_Name; //姓名 protected: string m_Car; //汽车 private: int m_Password; //银行卡密码 public: void func() { m_Name = "李四"; m_Car = "奔驰"; //保护权限内容,在类外访问不到 m_Password = 123; } }; int main() { //实例化具体对象 Person p1; p1.m_Name = "李四"; p1.m_Car = "奔驰"; //保护权限内容,在类外访问不到 p1.m_Password = 123; //私有权限内容,在类外访问不到 p1.func(); //公共权限内容,在类可以访问 system("pause"); return 0; } ``` ## 1.3 struct 和 class 区别 ① 在C++中struct和class唯一的区别就在于默认的访问权限不同。 ② 区别: 1. struct 默认权限为公共。 2. class 默认权限为私有。 ```python #include using namespace std; //访问权限 //三种 //公共权限 public 类内可以访问成员 类外可以访问成员 //保护权限 protected 类内可以访问成员 类外不可以访问成员 子类可以访问父类中的保护内容 //私有权限 private 类内可以访问权限 类外不可以访问成员 子类不可以访问父类中的私有内容 class C1 { int m_A; // 默认权限是私有 }; struct C2 { int m_A; //默认权限 是公共 }; int main() { //struct 和 class 区别 //struct 默认权限是 公共 public //class 默认权限是 私有 private C1 c1; c1.m_A = 100; //私有权限,不能访问 C2 c2; c2.m_A = 100; //公共权限,可以访问 system("pause"); return 0; } ``` ## 1.4 成员属性设置为私有 ① 优点1:将所有成员属性设置为私有,可以自己控制读写权限。 ② 优点2:可以通过写权限,检测数据的有效性。 ```python #include using namespace std; #include //成员属性设置为私有 //1、可以自己控制读写权限 //2、对于写可以检测数据的有效性 class Person { public: //设置姓名 void setName(string name) { m_Name = name; } //获取姓名 string getName() { return m_Name; } //获取年龄 int getAge() { m_Age = 0; //初始化为0岁 return m_Age; } void setLover(string lover) { m_Lover = lover; } private: //姓名 可读可写 string m_Name; //年龄 只读 int m_Age; //情人 只写 string m_Lover; }; int main() { Person p; p.setName("张三"); cout << "姓名为:" << p.getName() << endl; cout << "年龄为:" << p.getName() << endl; //p.m_Age = 18; //私有权限,不可以改 p.getAge(); cout << "姓名为:" << p.getAge() << endl; p.setLover("小李"); system("pause"); return 0; } ``` 运行结果: - 姓名为:张三 - 年龄为:0 - 请按任意键继续. . . ```python #include using namespace std; #include //成员属性设置为私有 //1、可以自己控制读写权限 //2、对于写可以检测数据的有效性 class Person { public: //设置姓名 void setName(string name) { m_Name = name; } //获取姓名 string getName() { return m_Name; } //获取年龄 可读可写 int getAge() { return m_Age; } //设置年龄 如果想修改(年龄的范围必须是0~150之间) void setAge(int age) { if (age < 0 || age>150) { m_Age = 0; //强制改为0 cout << "你这个老妖精!" << endl; return; //强制退出 } m_Age = age; } void setLover(string lover) { m_Lover = lover; } private: //姓名 可读可写 string m_Name; //年龄 只读 int m_Age; //情人 只写 string m_Lover; }; int main() { Person p; p.setName("张三"); cout << "姓名为:" << p.getName() << endl; //p.m_Age = 18; //私有权限,不可以类外改 p.setAge(1000); cout << "年龄为:" << p.getAge() << endl; //设置情人为苍井女士 p.setLover("小李"); //有这个函数可以设置 //cout << "情人为:" << p.getLover() << endl; //没有这个函数,不能获得 system("pause"); return 0; } ``` 运行结果: - 姓名为:张三 - 你这个老妖精! - 年龄为:0 - 请按任意键继续. . . ## 1.5 设计学生类 案例描述:设计一个学生类,属性有姓名和学号,可以给姓名和学号赋值,可以显示学生的姓名和学号。 ```python #include using namespace std; #include //设计学生类 class Student { public: //公共权限 //类中的属性和行为 我们统一称为成员 // 属性 成员属性 成员变量 // 行为 成员函数 成员方法 //属性 string m_Name; //姓名 int m_Id; //学号 //行为 //显示姓名和学号 void showStudent() { cout << "姓名:" << m_Name << " 学号:" << m_Id << endl; } //给姓名赋值的行为 void setName(string name) { m_Name = name; } }; int main() { //创建一个具体学生 实例化对象 Student s1; //给s1对象 进行属性赋值操作 s1.m_Name = "张三"; s1.m_Id = 1; s1.showStudent(); Student s2; s2.m_Name = "李四"; s2.m_Id = 2; s2.showStudent(); Student s3; s3.setName("王五"); s3.m_Id = 3; s3.showStudent(); system("pause"); return 0; } ``` 运行结果: - 姓名:张三 学号:1 - 姓名:李四 学号:2 - 姓名:王五 学号:3 - 请按任意键继续. . . ## 1.6 设计立方体类 案例描述:设计立方体类(Cube),求出立方体的面积和体积,分别用全局函数和成员函数判断两个立方体是否相等。 ```python #include using namespace std; //立方体类设计 //1、创建立方体类 //2、设计属性 //3、获取立方体面积和体积 //4、分别利用全局函数和成员函数 判断两个立方体是否相等 class Cube { public: //设置长 void setL(int l) { m_L = l; } //获取长 int getL() { return m_L; } //设置宽 void setW(int w) { m_W = w; } //获取宽 int getW() { return m_W; } //设置高 void setH(int h) { m_H = h; } //获取高 int getH() { return m_H; } //获取立方体面积 int calculateS() { return 2 * m_L * m_W + 2 * m_W * m_H + 2 * m_L * m_H; } //获取立方体体积 int calculateV() { return m_L * m_W * m_H; } //利用成员函数判断两个立方体是否相等 bool isSameByClass(Cube c) //成员函数只需要传入一个类为参数 { if (m_L == c.getL() && m_W == c.getW() && m_H == c.getH()) //类内可以访问成员函数:m_L、m_W、m_H { return true; } else { return false; } } private: int m_L; //长 int m_W; //宽 int m_H; //高 }; //利用全局函数判断,两个立方体是否相等 bool isSame(Cube c1, Cube c2) //值传递会拷贝一份数据,通过引用传递用原始数据,不会拷贝数据 { if (c1.getL() == c2.getL() && c1.getW() == c2.getW() && c1.getH() == c2.getH()) { return true; } else { return false; } } int main() { //创建立方体对象 Cube c1; c1.setL(10); c1.setW(10); c1.setH(10); cout << "c1的面积为:" << c1.calculateS() << endl; cout << "c1的体积为:" << c1.calculateV() << endl; Cube c2; c2.setL(10); c2.setW(10); c2.setH(11); bool ret = isSame(c1, c2); if (ret) { cout << "利用全局函数判断:c1和c2是相等的" << endl; } else { cout << "利用全局函数判断:c1和c2是不相等的" << endl; } //利用成员函数判断 ret = c1.isSameByClass(c2); if (ret) { cout << "利用成员函数判断:c1和c2是相等的" << endl; } else { cout << "利用成员函数判断:c1和c2是不相等的" << endl; } system("pause"); return 0; } ``` 运行结果: - c1的面积为:600 - c1的体积为:1000 - 利用全局函数判断:c1和c2是不相等的 - 利用成员函数判断:c1和c2是不相等的 - 请按任意键继续. . .