El puntero 'Self'
Parte de la sección Programación Orientada a Objetos del Journey de C de Coddy. Lección 7 de 61.
En lenguajes orientados a objetos como Python o Java, cuando llamas a object.method(), el lenguaje pasa automáticamente el propio objeto al método. En C, debemos hacerlo manualmente pasando un puntero a la estructura como primer argumento.
Este pointer se denomina convencionalmente self (tomado de Python) o this (de C++). Proporciona a la function acceso a los datos de struct para que pueda leerlos o modificarlos:
typedef struct {
int health;
} Player;
void player_take_damage(Player *self, int amount) {
self->health -= amount;
}
El puntero self es lo que hace que la función actúe como un método. Sabe qué jugador modificar. Sin él, la función no tendría forma de acceder a la instancia específica de la estructura. Al llamar a esta función, pasas la dirección de tu estructura:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health ahora es 75
Usar un puntero (en lugar de pasar la estructura directamente) es esencial para modificarla. Si pasaras la estructura por valor, la función recibiría una copia y cualquier cambio se perdería cuando la función terminara. El puntero garantiza que los cambios persistan en la estructura original.
Desafío
FácilConstruyamos un módulo Timer que registre los segundos transcurridos. Practicarás el uso del patrón del puntero «self» para modificar el estado interno de una estructura mediante funciones que actúan como métodos.
Crearás tres archivos:
timer.h: Declara una estructuraTimercon un único miembroint seconds. Declara también dos funciones:timer_tick(recibe un puntero a Timer y suma una cantidad especificada de segundos) ytimer_reset(recibe un puntero a Timer y vuelve a establecer seconds en cero). Usa protectores de inclusión con el símboloTIMER_H.timer.c: Implementa ambas funciones. La funcióntimer_tickdebe aceptar unTimer *selfy unint amount, y después sumar amount a los segundos del temporizador. La funcióntimer_resetdebe aceptar unTimer *selfy establecer sus segundos en cero.main.c: Crea un Timer, realiza operaciones con él y muestra los resultados.
Recibirás dos entradas enteras: los segundos iniciales de tu temporizador y la cantidad que se sumará mediante tick.
En tu archivo principal:
- Inicializa un
Timercon el valor de los segundos iniciales - Llama a
timer_tickpara sumar la cantidad especificada - Imprime los segundos actuales
- Llama a
timer_resetpara restablecer el temporizador - Imprime los segundos nuevamente (debería ser 0)
Imprime los resultados con este formato:
After tick: {seconds}
After reset: {seconds}Por ejemplo, con un valor inicial de 30 y sumando 15 segundos, la salida sería:
After tick: 45
After reset: 0Pruébalo tú mismo
#include <stdio.h>
#include "timer.h"
int main() {
int initial_seconds, amount_to_add;
scanf("%d", &initial_seconds);
scanf("%d", &amount_to_add);
// TODO: Crea un Timer e inicialízalo con initial_seconds
// TODO: Llama a timer_tick para añadir amount_to_add segundos
// TODO: Imprime los segundos actuales en el formato: "After tick: {seconds}"
// TODO: Llama a timer_reset para reiniciar el timer
// TODO: Imprime los segundos de nuevo en el formato: "After reset: {seconds}"
return 0;
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de programación modular
Archivos de cabeceraGuardas de inclusiónArchivos fuenteFunciones estáticasRepaso: Calculadora modular4Encapsulamiento
Concepto de punteros opacosDefinición de structs opacosGetters y SettersValidación en settersResumen: Caja secreta7Punteros a funciones
Declaración de punteros a funcionesLlamada a punteros a funcionesTypedef para punteros a funcionesPasar funciones como argumentosRepaso: Dispatch de calculadora10Contenedores genéricos
Repaso de punteros voidWrapper genéricoSwap genéricoComparación genéricaRepaso: Array genérico2Objetos y métodos
Structs como objetosEl puntero 'Self'Const CorrectnessPuntero vs. ValorMétodos auxiliaresResumen: Point Manager5Proyecto: Cuenta bancaria simple
Configuración del proyectoImplementación de la cuenta3Ciclo de vida de los objetos
Patrón ConstructorPatrón DestructorInicialización en StackCopia profundaResumen: String Wrapper6Herencia mediante composición
Incrustación de StructsLa regla del primer miembroAcceso a miembros padreUpcastingResumen: Jerarquía de formas9Proyecto: Dibujador de figuras
Descripción general del proyectoImplementación del círculoImplementación del rectánguloUso polimórficoContenedor de figurasPractica por tu cuenta: Compilador de C online