<s>[INST] I'm revising some legacy code written in C that doesn't follow good object-oriented practices, specifically related to encapsulation and data hiding.
While writing the code, it was considered important to follow the Single Responsibility Principle. But not to encapsulate data.

Here's a piece of code:
```c
// declarations.c
// API functions used throughout the project

// counter structure
typedef struct {
    int count;
    int limiter;
    char *key;
} counter_t;

// init function to set the count to 0, limiter to 5, and malloc memory for the string key
void counter_init(counter_t *counter) {
    // code to initialize
}

// query function to get the count from a counter struct
int counter_get_count(counter_t *counter) {
    return counter->count;
}

// update function to increment the count from a counter struct by limiter
void counter_update(counter_t *counter) {
    counter->count += counter->limiter;
}

// function to get the key for a counter struct
char *counter_get_key(counter_t *counter) {
    return counter->key;
}
```
I'd prefer to implement oo abstractions such as encapsulation in my revised code.
How do I refactor this C code to follow object-oriented programming abstractions?[/INST]