Menu
CoddyTech

获取器和设置器

本课属于 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

这种模式让你可以完全控制数据的访问方式:这是我们在下一课中添加设置器验证逻辑时要以此为基础的内容。

challenge icon

挑战

简单

让我们构建一个使用不透明指针模式以及 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;
}
quiz icon自我测试

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

面向对象编程中的所有课

自己练习: C 在线编译器