C
Opaque types
Learn opaque types and information hiding.
Opaque types
An opaque type hides its internal structure from the user. The header file contains only typedef struct Counter Counter;; the definition of struct Counter stays hidden in the source file.
The user holds a Counter * pointer but cannot access its contents. The struct is reached only through functions you provide (counter_new, counter_add, counter_get). This is the core way C achieves abstraction. Because the user does not know the internal layout, you can change it later without breaking user code. This pattern is common in real libraries; for example, the FILE type is opaque.
The Counter opaque type
A Counter opaque type accumulates a value through successive calls. The user sees only three functions: counter_new, counter_add and counter_get.
Example use: Counter *c = counter_new(); counter_add(c, 5); counter_add(c, 3); printf("%d\n", counter_get(c));. The output is 8. The user cannot write c->value because they cannot see the definition of struct Counter. This is a safe interface: only allowed operations can be performed. This pattern is C's equivalent of object-oriented programming; data and the functions that operate on it are packaged together.
Exercise Write an opaque Counter
Declare the opaque type with typedef struct Counter Counter;. Add the definition struct Counter { int value; };. Write Counter *counter_new(void), void counter_add(Counter *c, int n) and int counter_get(Counter *c). In main write Counter *c = counter_new(); counter_add(c, 5); counter_add(c, 3); printf("%d\n", counter_get(c)); free(c);.
Show example solution
#include <stdio.h>
#include <stdlib.h>
typedef struct Counter Counter;
struct Counter { int value; };
Counter *counter_new(void) {
Counter *c = malloc(sizeof(Counter));
c->value = 0;
return c;
}
void counter_add(Counter *c, int n) {
c->value += n;
}
int counter_get(Counter *c) {
return c->value;
}
int main(void) {
Counter *c = counter_new();
counter_add(c, 5);
counter_add(c, 3);
printf("%d\n", counter_get(c));
free(c);
return 0;
}
Test yourself
-
What is the advantage of an opaque type?
- Internal structure is hidden and can change later
- Automatic memory management
- Less memory usage
- Faster compilation
Show answer
Internal structure is hidden and can change later — An opaque type hides the internal structure; you can change it later without breaking user code.
-
Match the Counter functions
- counter_new
- New counter
- counter_add
- Add value
- counter_get
- Read value
- Counter *
- Opaque pointer
-
Complete the counter_add call
counter_add(c, ____);
Show answer
counter_add(c, 5);
Next lesson: typedef and enum