【C++】10_C++ 中 类 的封装

C++ 中 类 的封装

1.1 封装的声明

​ C++中对象的类型称为类(class),类代表了某一批对象的共性和特征,类是对象的抽象,而对象是类的具体实例(instance)。

​ 先声明一个类类型,然后用它去定义若干个同类型的对象。对象就是类类型的一个变量。可以说类是对象的模板,是用来定义对象的一种抽象类型。

​ 类是抽象的,不占用内存,而对象是具体的,占用存储空间。在一开始时弄清对象和类的关系是十分重要的。类是用户自己指定的类型。

​ 如果程序中要用到类类型,必须自己根据需要进行声明,或者使用别人已设计好的类。C++标准本身并不提供现成的类的名称、结构和内容。

class 类名{
	private:
		// 私有的成员变量(属性/数据) 和 成员函数(方法/行为)   
	protected:
		// 受保护的成员变量(属性/数据) 和 成员函数(方法/行为)   
	public:
		// 共有的成员变量(属性/数据) 和 成员函数(方法/行为)   
};

在这里插入图片描述

1.1.1 类声明示例

​ 设计一个学生类 获取学生的成绩

#include <iostream>
#include <string>

using namespace std;

// 学生类
class stu
{
public:     //访问权限  公共的权限
    // 成员属性
    string name;    // 姓名  
    int id;         // 学号
    string Class;   // 班级  
    int soc;        // 成绩

    // 成员函数 - 获取到学生的成绩
    void show_soc(void){
        cout << name << "的成绩 = " << soc << endl;
    }

protected:  //访问权限  保护的权限

private:    //访问权限  私有的权限

};



int main(int argc, char const *argv[])
{
    // 使用类定义变量的过程 我们称为 : 实例化对象
   		// 实例化对象
    stu s_arr[3] = {
        {.name = "张1" , .id = 1 , .Class = "1班" , .soc = 59},
        {.name = "张2" , .id = 2 , .Class = "1班" , .soc = 59},
        {.name = "张3" , .id = 3 , .Class = "1班" , .soc = 59},
    };
    
    for (size_t i = 0; i < 3; i++)
    {
        s_arr[i].show_soc();
    }
    
    
    return 0;
}

1.2 类的声明-访问权限

1.2.1权限的种类

访问控制权限:

  • public: 公共: 修饰的成员 在类内 子类 类外 都可以直接访问

  • protected: 保护: 修饰的成员 在类内 子类 可以直接访问 类外不行

  • private: 私有: 修饰的成员 在内类 可以直接访问 子类 类外 不行

1.2.2 权限间的关系
类内子类类外
public
protected×
private××

类的成员函数访问权限

  • 类的成员函数可以访问类的所有成员变量,包括 publicprotectedprivate。即使是通过函数传递过来的同类对象的私有成员,也可以访问。

访问控制是针对整个类

  • 访问控制是针对于整个类的,而不是某个具体的类对象。类内所有的成员函数和成员变量都受访问控制权限的影响。

访问控制的作用范围

  • 访问控制权限一旦声明,后面的所有成员都将遵循该权限,直到出现新的访问权限声明,或者类的定义结束。

访问控制声明的简洁性

  • 通常情况下,访问权限只需要在类内声明一次。多次声明是允许的,但不常见。

默认访问权限

  • 如果类中没有明确指定访问控制权限,默认情况下,所有成员都是 private

访问控制的目的

  • 访问控制的存在是为了保证类的正确使用。类的设计者通过设置访问权限,防止使用者以不合理的方式操作类的成员。例如,防止圆类的半径被赋值为负数等不合逻辑的操作。

1.3 类的声明-函数定义

在 C++ 中,类的成员函数可以通过两种方式声明和定义:

  • 类内声明,类外定义:在类的内部只进行函数的声明,而函数的定义在类的外部完成。

    • 通常用于保持类的定义简洁,便于维护较大的程序。
  • 类内声明,类内定义:在类的内部同时进行函数的声明和定义。

    • 适合简短的函数,能让类的定义更紧凑。

    在这里插入图片描述

1.3.1类内声明,类外定义
#include <iostream>
using namespace std;

class MyClass {
public:
    // 类内声明
    void printHllo();
};

// 类外定义
void MyClass::printMessage() {
    cout << "Hello" << endl;
}

int main() {
    MyClass obj;
    obj.printMessage();  // 调用类外定义的函数
    return 0;
}
1.3.2 类内声明,类内定义
#include <iostream>
using namespace std;

class MyClass {
public:
    // 类内声明和定义
    void printHllo() {
        cout << "Hello" << endl;
    }
};

int main() {
    MyClass obj;
    obj.printMessage();  // 调用类内定义的函数
    return 0;
}

1.4 类示例

#include <iostream>
#include <vector>
#include <string>
#include <stdexcept>

namespace School{
    /**
     * 学生类,封装学生姓名、学号和成绩,提供计算平均分和显示信息的方式。
     */
    class Student
    {
    private:
        std::string name;       // 学生姓名
        int id;                 // 学号
        std::vector<int> scores;// 存储成绩
    
    public:
        /**
         * 构造函数
         * @param n - 学生姓名
         * @param i - 学号
         */
        Student(const std::string & n, int i) : name(n), id(i){ } 

        /**
         * 添加成绩
         * @param score - 成绩(0~100 的整数)
         * 如果成绩不在范围内, 抛出 std::out_of_range 异常。
         */
        void addScore(int score){
            if (score >= 0 && score <= 100){
                scores.push_back(score);
            }else{
                throw std::out_of_range("成绩无效, 请输入 0 到 100 之间的分数。");
            }  
        }

        /**
         * 计算平均分
         * @return 平均分
         */
        double avgScore() const{
            if(scores.empty()){
                return 0.0;
            }
            int total = 0;
            for(int s : scores){
                total += s;
            }
            return static_cast<double>(total) / scores.size();
        }

        /**
         * 显示学生信息
         */
        void info() const{
            std::cout << "姓名: " << name
                      << "\n学号: " << id
                      << "\n平均分: " << avgScore() << std::endl;
        }

    };
    
}

int main(int argc, char const *argv[])
{
    School::Student stu("李四", 1001);  // 创建学生对象
    stu.info();

    stu.addScore(85);                   // 添加成绩
    stu.addScore(90);
    stu.addScore(78);

    stu.info();                          // 再次显示信息

    try {
        stu.addScore(110);                   // 测试无效成绩
    } catch (const std::out_of_range& e) {
        std::cerr << e.what() << std::endl;
    }
    try {
        stu.addScore(-5);
    } catch (const std::out_of_range& e) {
        std::cerr << e.what() << std::endl;
    }
    
    
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值