获取器和设置器
本课属于 Coddy C 学习旅程的“面向对象编程”单元。第 19 课,共 61 课。
使用不透明指针时,结构体的成员对外部代码是隐藏的。但如果外部代码无法直接访问数据,我们该如何读取或修改数据呢?答案是使用getter和setter函数:它们是公共接口,可以受控地访问私有数据。
getter 会返回隐藏成员的值:
// counter.h
int counter_get_value(const Counter *c);
// counter.c
int counter_get_value(const Counter *c) {
return c->value;
}
setter 会修改隐藏成员:
// counter.h
void counter_set_value(Counter *c, int new_value);
// counter.c
void counter_set_value(Counter *c, int new_value) {
c->value = new_value;
}
注意命名约定:在函数名前加上类型名称(counter_)作为前缀,以避免冲突并让 API 更清晰。Getter 使用 const 指针,因为它们不会修改对象。
现在,外部代码可以安全地与隐藏数据交互:
// main.c
Counter *c = create_counter(10);
printf("%d\n", counter_get_value(c)); // 10
counter_set_value(c, 25);
printf("%d\n", counter_get_value(c)); // 25
这种模式让你可以完全控制数据的访问方式:这是我们在下一课中添加设置器验证逻辑时要以此为基础的内容。
挑战
简单让我们构建一个使用不透明指针模式以及 getter 和 setter 函数的 Score 模块。你将创建一个隐藏的分数跟踪器,外部代码只能通过你提供的公共接口与数据交互。
你将创建 3 个文件:
score.h:公共接口。使用前向声明来声明不透明的Score类型(不要写结构体主体!)。声明以下函数:create_score:接收一个整数作为初始分数,并返回一个 Score 指针free_score:接收一个 Score 指针并释放内存score_get_points:getter,接收一个const Score *并返回当前分数score_set_points:setter,接收一个Score *和一个整数,并更新分数值
SCORE_H设置包含保护。score.c:定义实际的struct Score,其中只有一个隐藏成员:int points。实现全部 4 个函数。getter 应返回隐藏值,setter 应更新该值。请记住,getter 使用const指针,因为它们不会修改对象。main.c:通过创建分数、读取其值、使用 setter 修改分数,再次读取分数,来演示你的模块。
你会收到两个输入:要设置的初始分数(一个整数)和新分数值(一个整数)。
在主文件中,使用初始分数创建一个 Score,通过 getter 打印当前值,使用 setter 将其更新为新值,打印更新后的值,然后释放分数并打印确认信息。
按以下格式打印输出:
Initial: {points}
Updated: {points}
Freed例如,输入 100 和 250 时,输出如下:
Initial: 100
Updated: 250
Freed注意,main.c 无法直接访问 points。必须通过 getter 和 setter 函数来访问它。这就是封装的实际应用:你可以精确控制隐藏数据的读取和修改方式。
亲手试试
#include <stdio.h>
#include "score.h"
int main() {
int initial_points, new_points;
scanf("%d", &initial_points);
scanf("%d", &new_points);
// TODO:用 initial_points 创建一个 Score
// TODO:使用 getter 打印初始值
// 格式:"Initial: {points}"
// TODO:使用 setter 和 new_points 更新分数
// TODO:使用 getter 打印更新后的值
// 格式:"Updated: {points}"
// TODO:释放分数并打印 "Freed"
return 0;
}
这节课包含一个小测验。开始学习即可作答,并记录你的进度。
面向对象编程中的所有课
自己练习: C 在线编译器