Menu
CoddyTech

Getter 和 Setter

本课属于 Coddy C++ 学习旅程的“面向对象编程”单元。第 28 课,共 104 课。

当类成员是私有的,外部代码就无法直接访问它们。获取器和设置器是提供受控访问方式的公共方法。获取器用于获取值,设置器用于修改值。

class Temperature {
    double celsius;    // 私有,不能直接访问
    
public:
    // Getter:返回值
    double getCelsius() const {
        return celsius;
    }
    
    // Setter:验证后修改值
    void setCelsius(double value) {
        if (value >= -273.15) {    // 检查是否低于绝对零度
            celsius = value;
        }
    }
};

setter 的真正作用是验证。

你可以设置规则,而不是允许赋予任意值。在上面的示例中,低于绝对零度的温度会被拒绝。如果没有 setter,任何人都可以直接赋予无效数据。

getter 也可以在返回数据前转换数据:

class Temperature {
    double celsius;
public:
    double getCelsius() const { return celsius; }
    
    // 计算型 getter:不存储华氏温度,而是实时计算。
    double getFahrenheit() const {
        return celsius * 9.0 / 5.0 + 32.0;
    }
    
    void setCelsius(double value) { celsius = value; }
};

注意 getter 上的 const 关键字,这表示它们不会修改对象。setter 不能是 const,因为它们的作用是更改成员的值。使用 getter 和 setter 的这种模式是封装的基础,让你能够完全控制类数据的访问和修改方式。

challenge icon

挑战

简单

让我们构建一个玩家档案系统,展示 getter 和 setter 如何提供对私有数据的受控访问,包括验证和计算属性。

你将创建两个文件来组织代码:

  • Player.h:定义一个 Player 类,用受保护的数据访问方式管理游戏角色的档案。你的类应包含:
    • 私有成员:name(字符串)、level(int)和 experience(int)
    • 一个接收名称的构造函数,并将 level 初始化为 1,将 experience 初始化为 0
    • 一个 getter getName(),用于返回玩家的名称
    • 一个 getter getLevel(),用于返回当前等级
    • 一个 getter getExperience(),用于返回当前经验值
    • 一个 setter setName(),只接受至少包含 3 个字符的名称;如果名称无效,则保留当前名称不变
    • 一个 setter addExperience(int points),只接受正值。当经验值达到或超过 100 时,玩家升级:等级增加 1,经验值减去 100。如果增加的经验值足够多,这个过程可以发生多次。
    • 一个计算 getter getExperienceToNextLevel(),用于返回升到下一级还需要多少经验值(始终为 100 - current experience)

    将所有 getter 标记为 const,因为它们不会修改对象。

  • main.cpp:演示 getter 和 setter 的实际用法。从输入中读取玩家名称和要增加的经验值(各占一行),然后:
    • 使用输入的名称创建一个 Player
    • 打印 "Player: <name>, Level: <level>, XP: <experience>"
    • 使用 addExperience() 增加输入的经验值
    • 再次打印相同的状态行,以显示更新后的状态
    • 打印 "XP to next level: <amount>"
    • 尝试将名称改为 "Al"(验证应失败)
    • 打印 "Name after invalid change: <name>"
    • 将名称改为 "Champion"(验证应成功)
    • 打印 "Name after valid change: <name>"

经验值输入会以字符串形式提供,你需要将它转换为整数。在 main.cpp 中使用 #include "Player.h" 引入头文件。

亲手试试

#include <iostream>
#include <string>
#include "Player.h"

using namespace std;

int main() {
    // 读取玩家名称
    string playerName;
    getline(cin, playerName);

    // 读取要增加的经验值(先作为字符串读取,再转换为 int)
    string expString;
    getline(cin, expString);
    int expToAdd = stoi(expString);

    // TODO:用输入的名称创建一个 Player 对象

    // TODO:输出初始状态:"Player: <name>, Level: <level>, XP: <experience>"

    // TODO:使用 addExperience() 增加输入的经验值

    // TODO:输出更新后的状态行

    // TODO:输出 "XP to next level: <amount>"

    // TODO:尝试将名称改为 "Al"(验证应失败)

    // TODO:输出 "Name after invalid change: <name>"

    // TODO:将名称改为 "Champion"(应成功)

    // TODO:输出 "Name after valid change: <name>"

    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C++ 在线编译器