Getters and Setters
Part of the Object Oriented Programming section of Coddy's C journey — lesson 19 of 61.
With opaque pointers, the struct's members are hidden from outside code. But if external code can't access the data directly, how do we read or modify it? The answer is getter and setter functions—public interfaces that provide controlled access to private data.
A getter returns the value of a hidden member:
// counter.h
int counter_get_value(const Counter *c);
// counter.c
int counter_get_value(const Counter *c) {
return c->value;
}
A setter modifies a hidden member:
// 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;
}
Notice the naming convention: prefix functions with the type name (counter_) to avoid conflicts and make the API clear. Getters use const pointers since they don't modify the object.
Now external code can interact with the hidden data safely:
// 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
This pattern gives you complete control over how data is accessed—a foundation we'll build on in the next lesson when we add validation logic to setters.
Challenge
EasyLet's build a Score module that uses the opaque pointer pattern with getter and setter functions. You'll create a hidden score tracker where external code can only interact with the data through the public interface you provide.
You'll create three files:
score.h: Your public interface. Declare an opaqueScoretype using a forward declaration (no struct body!). Declare these functions:create_score— takes an integer for the initial points and returns a Score pointerfree_score— takes a Score pointer and releases memoryscore_get_points— a getter that takes aconst Score *and returns the current pointsscore_set_points— a setter that takes aScore *and an integer, updating the points value
SCORE_H.score.c: Define the actualstruct Scorewith a single hidden member:int points. Implement all four functions. Your getter should return the hidden value, and your setter should update it. Remember that getters useconstpointers since they don't modify the object.main.c: Demonstrate your module by creating a score, reading its value, modifying it through the setter, and reading it again.
You will receive two inputs: the initial points (an integer) and the new points value (an integer) to set.
In your main file, create a Score with the initial points, print the current value using the getter, update it using the setter with the new value, print the updated value, then free the score and print a confirmation.
Print the output in this format:
Initial: {points}
Updated: {points}
FreedFor example, with inputs 100 and 250, the output would be:
Initial: 100
Updated: 250
FreedNotice how main.c cannot access points directly—it must go through your getter and setter functions. This is encapsulation in action: you control exactly how the hidden data can be read and modified.
Cheat sheet
With opaque pointers, struct members are hidden from external code. To access or modify this private data, use getter and setter functions.
A getter returns the value of a hidden member and uses a const pointer since it doesn't modify the object:
// counter.h
int counter_get_value(const Counter *c);
// counter.c
int counter_get_value(const Counter *c) {
return c->value;
}
A setter modifies a hidden member:
// 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;
}
Use a naming convention with the type name as prefix (counter_) to avoid conflicts and clarify the API.
External code interacts with hidden data through these functions:
// 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
Try it yourself
#include <stdio.h>
#include "score.h"
int main() {
int initial_points, new_points;
scanf("%d", &initial_points);
scanf("%d", &new_points);
// TODO: Create a Score with initial_points
// TODO: Print the initial value using the getter
// Format: "Initial: {points}"
// TODO: Update the score using the setter with new_points
// TODO: Print the updated value using the getter
// Format: "Updated: {points}"
// TODO: Free the score and print "Freed"
return 0;
}
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Modular Programming Basics
Header FilesInclude GuardsSource FilesStatic FunctionsRecap: Modular Calculator4Encapsulation
Opaque Pointers ConceptDefining Opaque StructsGetters and SettersValidation in SettersRecap: Secret Box2Objects and Methods
Structs as ObjectsThe 'Self' PointerConst CorrectnessPointer vs ValueHelper MethodsRecap: Point Manager5Project: Simple Bank Account
Project SetupImplementation of Account3Object Lifecycle
Constructor PatternDestructor PatternStack InitializationDeep CopyRecap: String Wrapper6Inheritance via Composition
Struct EmbeddingThe First Member RuleAccessing Parent MembersUpcastingRecap: Shape Hierarchy