El puntero 'Self'
Parte de la sección Object Oriented Programming 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 self pointer es lo que hace que la función actúe como un método. Sabe qué Player modificar. Sin él, la función no tendría forma de acceder a la instancia específica de struct. Al llamar a esta función, pasas la dirección de tu struct:
Player hero = {100};
player_take_damage(&hero, 25);
// hero.health ahora es 75
Usar un pointer (en lugar de pasar el struct directamente) es esencial para realizar modificaciones. Si pasaras el struct por valor, la function recibiría una copia y cualquier cambio se perdería cuando la function devolviera el control. El pointer garantiza que los cambios persistan en el struct original.
Desafío
FácilConstruyamos un módulo Timer que registre los segundos transcurridos. Practicarás el uso del patrón de puntero "self" para modificar el estado interno de un struct mediante funciones que actúan como métodos.
Crearás tres archivos:
timer.h: Declare unTimerstructcon un único miembroint seconds. También Declare dos funciones:timer_tick(takes un pointer a Timer y add una cantidad especificada de seconds) ytimer_reset(takes un pointer a Timer y establece seconds de nuevo en cero). Usa include guards con el símboloTIMER_H.timer.c: Implement ambas funciones. La funcióntimer_tickdebe accept unTimer *selfy unint amount, y después add el amount a los seconds del timer. La funcióntimer_resetdebe accept unTimer *selfy establecer sus seconds en cero.main.c: Crea un Timer, realiza operaciones sobre él y muestra los resultados.
Recibirás dos entradas enteras: los initial seconds de tu timer y el amount to add mediante tick.
En tu archivo main:
- Inicializa un
Timercon el valor de initial seconds - Llama a
timer_tickpara add el amount especificado - Imprime los current seconds
- Llama a
timer_resetpara restablecer el timer - Imprime los seconds 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 add 15 seconds, 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 Object Oriented Programming
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