C++核心笔记(二)---类和对象(封装)

1、类和对象

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

C++认为万事万物都皆为对象,对象上有其属性和行为

例如:人可以作为对象,属性有姓名、年龄、身高、体重...,行为有走、跑、跳、吃饭、唱歌...,车也可以作为对象,属性有轮胎、方向盘、车灯.…,行为有载人、放音乐、放空调..,具有相同性质的对象,我们可以抽象称为,人属于人类,车属于车类

1.1 封装

1.1.1 封装的意义

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

封装的意义:

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

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

封装意义一:

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

语法:

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

类中的属性和行为,我们统一称为成员

        属性:也称成员属性、成员变量

        行为:也称成员函数、成员方法 

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

#include <iostream>
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 cl;
    //给圆对象 的属性进行赋值
    cl.m_r = 10;

    cout << "圆的周长为:" << cl.calculateZC() << endl;//所以这个地方可以直接算,不用赋值

    system("pause");
    return 0;
}

输出结果:

圆的周长为:62.8
请按任意键继续. . .

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

#include <iostream>
using namespace std;
#include<string>

//设计一个学生类,属性有姓名和学号,
//可以给姓名和学号赋值,可以显示学生的姓名和学号。

//设计学生类
class Student 
{
public://公共权限
    //属性
    string m_name;//名字
    int m_Id;//学号

    //行为
    //显示姓名和学号
    void showStudent()
    {
        cout << "姓名:" << m_name << " 学号:" << m_Id << endl;
    }

    //给姓名赋值
    void setName(string name)
    {
        m_name = name;
    }

    //给学号赋值
    void setId(int id)
    {
        m_Id = id;
    }
};


int main()
{
    //创建具体的学生(对象)
    //实例化对象  (通过一个类,创建一个对象的过程)
    Student s1;
    //给s1对象 的属性进行赋值
    //s1.m_name = "张三";
    s1.setName("张三");//两种方法给名字赋值都可以
    //s1.m_Id = 1;
    s1.setId(1);//两种方法给学号赋值都可以
    //显示学生信息
    s1.showStudent();//所以这个地方可以直接算,不用赋值

    Student s2;
    //s2.m_name = "李四";
    s2.setName("李四");//和上述同理
    //s2.m_Id = 2;
    s2.setId(2);
    s2.showStudent();

    system("pause");
    return 0;
}

输出结果:

姓名:张三 学号:1
姓名:李四 学号:2
请按任意键继续. . .

封装意义二:

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

访问权限有三种:

        1、public           公共权限        成员类内可以访问         类外可以访问

        2、protected     保护权限        成员类内可以访问         类外不可以访问

        3、private         私有权限        成员类内可以访问         类外不可以访问

后两者的区别:继承的时候有区别,儿子可以访问父亲中的保护内容,但是儿子不可以访问父亲中的私有内容

#include <iostream>
using namespace std;
#include<string>

//访问权限
class Person 
{
public:
    //公共权限
    string m_Name;//姓名

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

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

private://无论这里是什么权限,函数里面(因为在类内)都可以访问
    void func()
    {
        m_Name = "张三";
        m_Car = "拖拉机";
        m_Password = 123456;
    }
};

int main()
{
    //实例化对象  (通过一个类,创建一个对象的过程)
    Person p1;

    p1.m_Name = "李四";
    //p1.m_Car = "奔驰";//保护权限内容,在类外不可以访问
    //p1.m_Password = 123;//私有权限内容,在类外不可以访问
    //p1.func();//因为是私有权限,所以不能访问,如果改为public就可以访问

    system("pause");
    return 0;
}

1.1.2struct和class的区别

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

        区别:

                struct默认权限为公共public

                class默认权限为私有private

#include <iostream>
using namespace std;

//struct和class的区别
class C1
{
    int m_A;//默认权限 是私有
};

struct C2
{
    int m_A;//默认权限 是公共
};

int main()
{
    //实例化对象  (通过一个类,创建一个对象的过程)
    C1 c1;
    //c1.m_A = 100;//私有权限内容,在类外不可以访问

    C2 c2;
    c2.m_A = 100;//公共权限内容,在类外可以访问

    system("pause");
    return 0;
}

1.1.3成员属性设置为私有

        优点1、将所有的成员属性设置为私有,可以自己控制读写权限

        优点2、对于写权限,我们可以检测数据的有效性

#include <iostream>
using namespace std;
#include<string>

//成员属性设置为私有
//优点1、将所有的成员属性设置为私有,可以自己控制读写权限

//优点2、对于写权限,我们可以检测数据的有效性
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)
        {
            cout << "年龄" << age << "输入有误,赋值失败!" << endl;
            return;
        }
        m_Age = age;
    }

    //设置偶像
    void setIdol(string idol)
    {
        m_Idol = idol;
    }
private:
    string m_Name;//姓名 可读可写
    int m_Age = 18;//年龄 只读  也可以写(年龄必须在0-150之间)
    string m_Idol;//偶像 只写
};

int main()
{
    //实例化对象  (通过一个类,创建一个对象的过程)
    Person p;
    //姓名设置
    p.setName("张三");
    //获取姓名
    cout << "姓名:" << p.getName() << endl;

    //年龄设置
    //m_Age = 20;
    p.setAge(160);
    //获取年龄
    cout << "年龄:" << p.getAge() << endl;

    //偶像设置
    p.setIdol("小明");
    //cout << "偶像为:" << m_Idol << endl;//无法访问
    
    system("pause");
    return 0;
}

输出结果:

姓名:张三
年龄160输入有误,赋值失败!
年龄:18
请按任意键继续. . .

练习案例1---设计立方体类(Cube)

求出立方体的面积和体积

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

#include <iostream>
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_L * m_H + 2 * m_W * m_H;
    }
    //获取立方体体积
    int caiculateV()
    {
        return m_L * m_W * m_H;
    }
    //利用成员函数判断两个立方体是否相等
    bool isSameByClass(Cube &c)
    {
        if (m_L == c.getL() && m_W == c.getW() && m_H == c.getH())
        {
            return true;
        }
        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;
    }
    return false;
}

int main()
{
    //实例化 创建立方体对象
    Cube c1;
    c1.setL(10);
    c1.setW(10);
    c1.setH(10);

    cout << "c1的面积为:" << c1.calculateS() << endl;
    cout << "c1的体积为:" << c1.caiculateV() << endl;
    
    //创建第二个立方体
    Cube c2;
    c2.setL(10);
    c2.setW(10);
    c2.setH(10);

    //利用全局函数判断 两个立方体是否相等
    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是相等的
请按任意键继续. . .

练习案例2---点和圆的关系

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

本案例核心内容:

1、在类中可以让另一个类作为本来的成员(此案例中圆的圆心坐标)

2、可以把相应的点类、圆类拆成不同的.h和.cpp文件,代码简洁,而且符合工程实际(具体方法可以参考一下C++基础笔记(五)的1.6函数分文件编写,两者稍有区别)

#include <iostream>
using namespace std;
//#include<string>

//点和圆关系案例

// 点类设计
class Point
{
public://对外提供公共接口
    //设置x
    void setX(int x)
    {
        m_X = x;
    }
    //获取x
    int getX()
    {
        return m_X;
    }
    //设置y
    void setY(int x)
    {
        m_Y = x;
    }
    //获取y
    int getY()
    {
        return m_Y;
    }
private:
    int m_X;//X坐标
    int m_Y;//Y坐标
};

//圆类设计
class Circle
{
public:
    //设置半径
    void setR(int r)
    {
        m_R = r;
    }
    //获取半径
    int getR()
    {
        return m_R;
    }
    //设置圆心
    void setCenter(Point center)
    {
        m_Center = center;
    }
    //获取圆心
    Point getCenter()//返回Point类的变量
    {
        return m_Center;
    }
private:
    int m_R;//半径

    //在类中可以让另一个类 作为本来的成员
    Point m_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 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);

    //创建点
    Point p;
    p.setX(10);
    p.setY(10);

    //判断关系
    isInCircle(c, p);
    
    system("pause");
    return 0;
}

输出结果:

点在圆上
请按任意键继续. . .
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值