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 的这种模式是封装的基础,让你能够完全控制类数据的访问和修改方式。
挑战
简单让我们构建一个玩家档案系统,展示 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;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C++ 在线编译器