黑马程序员C++核心编程笔记--4 类和对象--封装

发布于:2025-06-04 ⋅ 阅读:(31) ⋅ 点赞:(0)

C++面向对象三大特征:封装、继承、多态

C++认为万事万物皆对象,对象有其属性和行为,具有相同性质的对象可以抽象称为

4.1 封装

4.1.1 封装的意义

  • 将属性和行为作为一个整体,表现生活中的事物
  • 将属性和行为加以权限控制

在设计类的时候,属性和行为写在一起,表现事物

语法:class 类名{ 访问权限: 属性/行为}

示例一:设计一个圆类,求圆的周长

#include <iostream>
using namespace std;

// 设计一个圆类,求圆的周长
// 圆周率:3.14
const double PI = 3.14;

class Circle {
public:

    // 属性
    int m_r;    //  半径

    // 行为
    // 获取圆的周长
    double calculateZC() {
        return 2*PI*m_r;
    }
};

int main() {

    // 通过圆类创建一个具体的圆(对象)
    // c就是一个具体的圆(对象)
    Circle c;
    c.m_r = 10;     // 给圆对象的半径赋值
    cout << c.calculateZC() << endl;
    return 0;
}

示例二:设计一个学生类,属性有姓名和学号,可以给姓名和学号进行赋值,可以显示学生的姓名和学号

#include <iostream>
using namespace std;

class Student {
public:

    // 属性
    string s_name;
    int m_id;

    // 行为
    // 给姓名和学号进行赋值操作
    void setName(string name) {
        s_name = name;
    }
    void setId(int id) {
        m_id = id;
    }
    // 显示姓名和学号
    void showInfo() {
        cout << s_name << " " << m_id << endl;
    }

};

int main() {
    Student s1{"张三", 001};
    s1.showInfo();

    Student  s2;
    s2.setName("homo");
    s2.setId(111);
    s2.showInfo();
}

4.1.2 访问权限

  • public: 公有属性,类外可以访问
  • private: 私有属性,类外不可以访问
  • protected: 保护属性,类外不可以访问,类内可以访问,子类可以访问

示例:

#include <iostream>
using namespace std;

class Person {
    // 姓名 公共权限
    public:
        string m_name;

    // 汽车 保护权限
    protected:
        string m_car;

    // 银行密码 私有权限
    private:
        int m_password;

    // 行为
    public:
    void func() {
        m_name = "张三";
        m_car = "保时捷";
        m_password = 123456;
    }
    void showInfo() {
        cout << "姓名:" << m_name << endl;
        cout << "汽车:" << m_car << endl;
        cout << "密码:" << m_password << endl;
    }
};

int main() {

    Person p1;
    p1.m_name = "homo";
    cout << p1.m_name << endl;
    // p1.m_car = "拖拉机"; 报错,保护权限类外无法访问
    // cout << p1.m_car << endl;
    // p1.m_password = 987654; 报错,私有权限类外无法访问
    // cout << p1.m_password << endl;


    Person p2;
    p2.func();
    cout << p2.m_name << endl;
    // cout << p2.m_car << endl; 同样报错,只能通过公开函数访问
    // cout << p2.m_password << endl; 同样报错,只能通过公开函数访问
    p2.showInfo();      // 正确,通过公开函数访问
}

4.1.3 C++中class和struct的区别

在C++中 struct和class唯一的区别就在于默认的访问权限不同

区别:

  • struct 默认属性是public
  • class 默认属性是private

示例:

#include <iostream>

using namespace  std;

class c1 {
    int m_a;    // 默认是私有变量
};

struct s1 {
    int m_a;    // 默认是公共变量
};

int main() {
    c1 c;
    s1 s;
    // c.m_a = 1;   错误,私有变量不能被访问
    s.m_a = 2;      //  正确,公共变量可以被访问
    // cout << c.m_a << endl;   错误,私有变量不能被访问
    cout << s.m_a << endl;      //  正确,公共变量可以被访问
    return 0;
}

4.1.4成员属性设置为私有

  • 优点1:可以自己控制读写权限
  • 优点2:对于写权限,我们可以检测数据的有效性

示例:

#include <iostream>
#include <string>

using namespace std;

class Person {
  // 公有方法对私有属性进行控制
public:
  // 姓名:可读可写
  // 姓名的写操作:设置姓名
  void setName(string name) {
    m_Name = name;
  }
  // 姓名的读操作:获取姓名
  string getName() {
    return m_Name;
  }


  // 年龄设置可读可写
  // 获取年龄
  int getAge() {
    return m_Age;
  }
  // 年龄设置可读可写
  void setAge(int age) {
    if (age >= 0 && age <= 150)
      m_Age = age;
    else {
      cout << "年龄需要在0-150之间" << endl;
      return;   // 年龄输入有误,返回
    }
  }

  // 情人设置可写
  void setLover(string lover) {
    m_lover = lover;
  }
private:
  string m_Name;  // 姓名 可读可写
  int m_Age = 18;  //  年龄 可读可写,但只能在0-150之间
  string m_lover; // 情人 只写

};

int main() {
  Person p;
  // 写姓名
  p.setName("aj");
  // 读姓名
  cout << "姓名:" << p.getName() << endl;

  // 写年龄
  p.setAge(20);
  // 读年龄
  cout << "年龄:" << p.getAge() << endl;

  return 0;
}

4.1.5 设计案例1 立方体类

设计立方体类(Cube),求出立方体的面积体积

分别用全局函数成员函数判断两个立方体是否相等。

示例:

//
// 设计立方体类(Cube),求出立方体的面积和体积。
// 分别用全局函数和成员函数判断两个立方体是否相等。
//
#include <iostream>
using namespace std;

class Cube
{
    // 属性
private:
    double m_L;     //长
    double m_W;     //宽
    double m_H;     //高

    // 行为
public:
    // 属性为私有,设置方法获取长宽高
    // 设置长
    void setL(double L) {
        m_L = L;
    }
    // 获取长
    double getL() {
        return m_L;
    }
    // 设置宽
    void setW(double W) {
        m_W = W;
    }
    // 获取宽
    double getW() {
        return m_W;
    }
    // 设置高
    void setH(double H) {
        m_H = H;
    }
    // 获取高
    double getH() {
        return m_H;
    }

    // 求立方体的面积
    double getArea() {
        return 2*(m_L*m_W+m_L*m_H+m_W*m_H);
    }

    // 求立方体的体积
    double Volume() {
        return m_L*m_W*m_H;
    }

    // 成员函数判断两个立方体是否相等
    bool isEqualByClass(Cube & c) {
        if (m_L == c.getL() && m_W == c.getW() && m_H == c.getH())
            return true;
        else
            return false;
    }
};

// 全局函数:判断两个立方体是否相等
// 思路:分别比较两个立方体的长宽高是否相等,如果相等则认为两个立方体相等
bool isEqual(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(20);
    c1.setH(30);
    cout << "c1的面积为:" << c1.getArea() << endl;
    cout << "c1的体积为:" << c1.Volume() << endl;

    cout << "--------------------" << endl;
    Cube c2;
    c2.setL(10);
    c2.setW(20);
    c2.setH(30);
    cout << "c2的面积为:" << c2.getArea() << endl;
    cout << "c2的体积为:" << c2.Volume() << endl;

    cout << "--------------------" << endl;
    // 全局函数判断两个立方体是否相等
    bool a = isEqual(c1, c2);
    if (a)
        cout << "两个立方体相等" << endl;
    else
        cout << "两个立方体不相等" << endl;
    cout << endl;
    // 成员函数判断两个立方体是否相等
    bool b = c1.isEqualByClass(c2);
    if (b)
        cout << "成员函数判断:两个立方体相等" << endl;
    else
        cout << "成员函数判断:两个立方体不相等" << endl;
}

4.1.6 设计案例2 点和圆关系

设计一个圆形类(Circle),和一个点类(Point),计算点和圆的关系。

示例:

//
// 设计一个圆形类(Circle),和一个点类(Point),计算点和圆的关系。
//
#include <iostream>
using namespace std;

// 点类
class Point {

private:
    int m_X;
    int m_Y;

// 对外提供公有接口
public:
    // 设置x坐标
    void SetX(int x) {
        m_X = x;
    }
    // 获取x坐标
    int GetX() {
        return m_X;
    }
    // 设置y坐标
    void SetY(int y) {
        m_Y = y;
    }
    // 获取y坐标
    int GetY() {
        return m_Y;
    }
};
// 圆类
class Circle {
private:
    // 半径
    int m_R;

    // 圆心
    Point m_Center;     // 在类中可以让另一个类的属性作为成员变量

public:
    // 设置半径
    void setR(int r) {
        m_R = r;
    }
    // 获取半径
    int getR() {
        return m_R;
    }
    // 设置圆心
    void setCenter(Point center) {
        m_Center = center;
    }
    // 获取圆心
    Point getCenter() {
        return m_Center;
    }


};
// 判断点和圆的关系
// 圆心到点距离小于半径,则点在圆内;圆心到点距离大于半径,则点在圆外;圆心到点距离等于半径,则点在圆上。
void isInCircle(Circle &c, Point &p) {
    // 点到圆心距离计算公式:sqrt((x1-x2)^2 + (y1-y2)^2)
    // 简化代码:既然只要我们比较点到圆心的距离与半径,那么可以省去点到远近距离计算的根号,用左侧和右侧同时平方进行比较。

    // 计算两点之间距离的平方
    int distance = (c.getCenter().GetX()-p.GetX())*(c.getCenter().GetX()-p.GetX()) +
        (c.getCenter().GetY()-p.GetY())*(c.getCenter().GetY()-p.GetY());

    // 计算半径的平方
    int rDistance = c.getR() * c.getR();

    // 判断关系
    if (distance < rDistance) {
        cout << "点在圆内" << endl;
    }
    else if (distance > rDistance) {
        cout << "点在圆外" << endl;
    }
    else {
        cout << "点在圆上" << endl;
    }
}
int main() {

    // 创建圆
    Circle c;
    c.setR(10);
    Point center;   // 创建圆心
    center.SetX(10);
    center.SetY(0);
    c.setCenter(center);
    cout << "圆的半径为:" << c.getR() << endl;
    cout << "圆的圆心为:" << c.getCenter().GetX() << " " << c.getCenter().GetY() << endl;

    // 创建点
    Point p;
    p.SetX(10);
    p.SetY(10);

    // 判断关系
    isInCircle(c, p);

    return 0;
}

网站公告

今日签到

点亮在社区的每一天
去签到