C++中的 封装

目录

1 封装

1.1 封装的意义

1.2 语法

1.3 示例

1.3.1 示例1

1.3.2 示例2

1.4 将属性和行为加以权限控制

1.5 struct与class的区别

1.5.1 示例

1.6 成员属性设置为私有

1.7 示例

1.7.1 示例1

1.7.2 示例2


1 封装

1.1 封装的意义

封装是C++面向对象三大特性之一

1.2 语法

 class name
 {
 访问权限:
 ​
         属性
 ​
         行为
 };

注意:类中的属性和行为 统称为成员

  • 属性 又称 成员属性 / 成员变量

  • 行为 又称 成员函数 / 成员方法

封装将属性和行为作为一个整体,表现生活中的事物


1.3 示例

1.3.1 示例1

接下来创建一个圆类,以计算圆的周长

创建圆类:

// 创建一个 圆 类,class后跟着的就是类的名称
 class Circle
 {
     // 访问权限
 public:// 公共权限
 ​
     // 属性
     int r; // 半径
 ​
     // 行为
     double caculate_perimeter() // 计算圆的周长
     {
         return 2 * PI * r;
     }
 };

主函数

实例化:通过类创建一个对象的过程

 #define PI 3.14
 int main()
 {    //   实例化:通过类创建一个对象的过程
     Circle c; // 通过 圆 类创建具体的圆(对象) 
 ​
     cin >> c.r; // 给 圆 对象 的属性赋值
 ​
     cout << "半径为" << c.r << "的圆的周长为" << c.caculate_perimeter() << endl;
     return 0;
 }

img

1.3.2 示例2

设计一个学生类,属性有姓名和学号,行为可以给学生姓名和学号赋值,而且可以显示学生姓名和学号

class student
 {
 public:
 ​
     // 属性:姓名 学号
     string s_name;
     int s_number;
 ​
     // 行为:给姓名与学号赋值/显示
     void show()
     {
         cout << "学生姓名为" << s_name << endl;
         cout << "学生学号为" << s_number;
     }
     // 赋值
     void assignment1() // 键盘输入
     {
         cout << "请输入姓名" << endl;
         cin >> s_name;
         cout << endl;
         cout << "请输入学号" << endl;
         cin >> s_number;
     }
     void assignment2(string name,int Studnet_number)// 直接传参
     {
         s_name = name;
         s_number = Studnet_number;
     }
 };

对于给姓名和学号赋值,有2种方法

  • 直接键盘cin

  • 调用函数时直接传参

方法不同,调用函数时写法也不同

 int main()
 {
     student s1;
     s1.assignment1();   //1键盘cin输入
     s1.assignment2("joyce", 32054123); // 2直接传参
     s1.show();
 ​
     return 0;
 }

1.4 将属性和行为加以权限控制

类在设计时,可以把属性和行为放在不同的权限下,加以控制

访问权限有3种:

名称作用范围不同点
public公共权限类内可以访问,类外可以访问\
protected保护权限类内可以访问,类外不可以访问继承关系中,子可以使用父的
private私有权限类内可以访问,类外不可以访问继承关系中,子不能使用父的

示例:

 class person
 {
 public:
     string name;// 姓名,公共权限
 ​
 protected:
     string car;// 汽车,保护权限
 ​
 private:
     int password;// 密码,私有权限
 };
 ​
 int main()
 {
     person p;
     p.name = "joyce";// 只有公共权限在类外才可以访问
     p.car = "BMW";
     p.password = 131221;
     return 0;
 }

img

不过,如果在类内定义一个公共权限的函数,以访问各个权限的属性,则

 class person
 {
 public:
     string name;// 姓名,公共权限
 ​
 protected:
     string car;// 汽车,保护权限
 ​
 private:
     int password;// 密码,私有权限
 ​
 public: //类内定义的公共权限的函数
     void func()
     {
         string name = "nana";
         string car = "BMW";
         int password = 19931312;
     }
 };

在main函数中调用func函数,则可以访问保护权限和私有权限的属性

     p.func();

不过若是将函数的权限从public改为protected或是private,则仍然无法访问

1.5 struct与class的区别

区别在于 默认的访问权限不同

名称默认访问权限
structpublic公共权限
classprivate私有权限

1.5.1 示例

创建struct和class两个类型

 struct P1
 {
     int a;
 };
 class P2
 {
     int a;
 };
在main函数中
创建变量并尝试访问
 int main()
 {
     P1 p1; // 结构体
     p1.a = 5;
 ​
     P2 p2; // 类
     p2.a = 5;
     return 0;
 }

img

1.6 成员属性设置为私有

作用:

  • 可以自己控制成员的读写权限

 class My
 {
 public:
     void setname(string name)// 设置姓名
     {
         m_name = name;
     }
     string getname() // 返回姓名
     {
         return m_name;
     }
 ​
     int getage() // 返回年龄,无法修改
     {
         return age;
     }
 ​
     void setPassword(int password) // 修改密码,无法查看
     {
         m_Password = password;
     }
 private:
     string m_name; // 设置为可读可写
     int age = 5; // 设置为只读
     int m_Password; // 设置为只写
 };

接下来使用各个函数,修改或查看各个属性

int main()
 {
     My m;
     m.setname("joyce"); // 设置姓名
     cout << m.getname() << endl; // 查看姓名
 ​
     cout << m.getage() << endl;// 查看年龄
     //m.age = 6; // 若想修改年龄,无法访问
 ​
     m.setPassword(3171321); // 修改密码,无法查看
     m.m_Password; 
 ​
     return 0;
 }

img

img

可读可写权限的姓名,可以修改或是查看

img

  • 对于写可以检测数据的有效性

在上面类中,我们在查看年龄getage函数下,加上设置年龄setage函数

     void setage(int age) // 设置年龄,范围0-150
     {
         if (age < 0 || age>150)
         {
             cout << "Input errot!" << endl;
             m_age = 0;
             return;
         }
         m_age = age;
     }

加以判断,若年龄不在0-150,则报错,满足才修改年龄

1.7 示例

1.7.1 示例1

设计一个正方体类,获取正方体长宽高,计算出正方体面积和体积,并分别用全局函数和成员函数判断两个立方体是否相等

 class Cube
 {
 public:
     // 设置与获取长宽高
     void setCube(int L, int W, int H)
     {
         m_L = L;
         m_W = W;
         m_H = H;
     }
     int getL()
     {
         return m_L;
     }
     int getW()
     {
         return m_W;
     }
     int getH()
     {
         return m_H;
     }
     // 获取正方体面积
     int calculateArea()
     {
         return 2 * (m_L * m_W + m_L * m_H + m_W * m_H);
     }
     // 获取正方体体积
     int calculateVolume()
     {
         return m_L * m_W * m_H;
     }
     //2、用成员函数判断2个Cube是否相等
     bool Judge2(Cube& cube)
     {
         if (getH() == cube.getH() &&
             getL() == cube.getL() &&
             getW() == cube.getW())
             return true;
         return false;
     }
 private:
     int m_L, m_W, m_H;
 };
 ​
 // 1、用全局函数判断2个Cube是否相等
 bool Judge1(Cube&cube1 ,Cube&cube2)
 {
     if (cube1.getH() == cube2.getH() &&
         cube1.getL() == cube2.getL() &&
         cube1.getW() == cube2.getW())
         return true;
     return false;
 }
 int main()
 {
     // 创建第一个Cube
     Cube cube1;
     cube1.setCube(10,10,10);
     /*cout << "正方体面积为" << cube1.calculateArea() << endl;
     cout << "正方体体积为" << cube1.calculateVolume() << endl*/;
 ​
     // 创建第二个Cube
     Cube cube2;
     cube2.setCube(10, 10, 10);
 ​
     bool ret1 = Judge1(cube1,cube2); // 全局变量调用的对比
     if (ret1)
         cout << "cube1和cube2相等" << endl;
     else
         cout << "cube1和cube2不相等" << endl;
 ​
     bool ret2 = cube1.Judge2(cube2); // 成员函数调用的对比
     if (ret2)    
         cout << "cube1和cube2相等" << endl;
     else
         cout << "cube1和cube2不相等" << endl;
     return 0;
 }

img

两函数都相等

img

两函数都不相等

1.7.2 示例2

设计一个圆类和点类,属性包括圆和点的横坐标x和纵坐标y以及两点之间距离和圆的半径,并判断点在圆的什么位置(上、内、外)

点类:point.h头文件

 class point //  点 类
 {
 public:
     void setx(int x); // 设置点的横坐标x
 ​
     int getx();
 ​
     void sety(int y);// 设置点的纵坐标y
 ​
     int gety();
 ​
 private:
     int p_x;
     int p_y;
 };

源文件:point.cpp

 void point::setx(int x) // 设置点的横坐标x
 {
     p_x = x;
 }
 int point::getx()
 {
     return p_x;
 }
 void point::sety(int y) // 设置点的纵坐标y
 {
     p_y = y;
 }
 int point::gety()
 {
     return p_y;
 }

注意:在各个头文件中原来的各个函数都是全局函数,但每个函数都是成员函数,因此要加上它自己作用域下的函数point::/circle::

圆类:头文件:circle.h

 class circle // 设置 圆 类
 {
 public:
     void setr(int r); // 设置半径
 ​
         int getr();
 ​
         void setCenter(point center); // 设置圆心,本质也是个半径
 ​
         point getCenter();
 ​
 private:
     int c_r; 
     point c_center;// 一个类中可以包含另一个类,作为原来类的成员
 };

源文件:circle.cpp

 void circle::setr(int r) // 设置半径
 {
     c_r = r;
 }
 int circle::getr()
 {
     return c_r;
 }
 void circle::setCenter(point center) // 设置圆心,本质也是个半径
 {
     c_center = center;
 }
 point circle::getCenter()
 {
     return c_center;
 }

计算距离、半径平方以及判断

 void IsInCircle(circle &c,point &p) // 判断两点之间关系
 {
     // 计算两点之间距离
     int distance=
     (c.getCenter().getx() - p.getx()) * (c.getCenter().getx() - p.getx()) +
     (c.getCenter().gety() - p.gety()) * (c.getCenter().gety() - p.gety());
 ​
     // 计算半径的平方
     int square = c.getr() * c.getr();
 ​
     // 判断距离和平方的关系
     if        (distance == square)
         cout << "在圆上" << endl;
     else if (distance > square)
         cout << "在圆外" << endl;
     else
         cout << "在圆内" << endl;
 }

main函数

 int main()
 {
     // 创建圆
     circle c;
     c.setr(1);
     point center;
     center.setx(2);
     center.sety(2);
     c.setCenter(center);
 ​
     // 创建点
     point p;
     p.setx(2);
     p.sety(1);
 ​
     IsInCircle(c, p);
 ​
     return 0;
 }

  • 13
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 C 语言,没有类的概念,但是可以使用结构体和函数指针等技术来实现面向对象编程的一些特性。下面是一个简单的封装 TCP 的例子,使用了结构体和函数指针来实现。 首先,我们定义一个结构体来表示 TCP 连接: ```c typedef struct { int sockfd; } tcp_t; ``` 其,`sockfd` 表示套接字文件描述符,即表示 TCP 连接的句柄。接下来,我们定义一些操作 TCP 连接的函数: ```c typedef int (*tcp_connect_func_t)(tcp_t *tcp, const char *host, int port); typedef int (*tcp_send_func_t)(tcp_t *tcp, const void *buf, size_t len); typedef int (*tcp_recv_func_t)(tcp_t *tcp, void *buf, size_t len); typedef void (*tcp_close_func_t)(tcp_t *tcp); ``` 这里使用了函数指针,将这些操作函数作为结构体的成员,可以方便地进行封装。 接下来,我们定义一个 TCP 类,包括一些操作函数的实现: ```c typedef struct { tcp_t tcp; tcp_connect_func_t connect; tcp_send_func_t send; tcp_recv_func_t recv; tcp_close_func_t close; } tcp_class_t; int tcp_connect(tcp_class_t *tcp, const char *host, int port) { return tcp->connect(&tcp->tcp, host, port); } int tcp_send(tcp_class_t *tcp, const void *buf, size_t len) { return tcp->send(&tcp->tcp, buf, len); } int tcp_recv(tcp_class_t *tcp, void *buf, size_t len) { return tcp->recv(&tcp->tcp, buf, len); } void tcp_close(tcp_class_t *tcp) { tcp->close(&tcp->tcp); } ``` 这里使用了结构体嵌套,将 `tcp_t` 结构体作为 `tcp_class_t` 的成员,实现了 TCP 连接的封装。其,`tcp_connect`、`tcp_send`、`tcp_recv`、`tcp_close` 分别对应 TCP 连接的连接、发送、接收和关闭操作。 最后,我们可以使用这个 TCP 类来创建 TCP 连接: ```c tcp_class_t tcp = { .tcp = { .sockfd = -1 }, .connect = tcp_connect_impl, .send = tcp_send_impl, .recv = tcp_recv_impl, .close = tcp_close_impl }; if (tcp.connect(&tcp, "example.com", 80) == -1) { perror("tcp.connect"); return 1; } char buf[1024]; if (tcp.send(&tcp, "GET / HTTP/1.1\r\n\r\n", strlen("GET / HTTP/1.1\r\n\r\n")) == -1) { perror("tcp.send"); return 1; } if (tcp.recv(&tcp, buf, sizeof(buf)) == -1) { perror("tcp.recv"); return 1; } tcp.close(&tcp); ``` 这里创建了一个 `tcp_class_t` 对象,调用其成员函数来连接、发送、接收和关闭 TCP 连接。具体

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值