Patrón Constructor
Parte de la sección Programación Orientada a Objetos del Journey de C de Coddy. Lección 12 de 61.
En lenguajes como Java o C++, creas objetos usando constructores: funciones especiales que asignan memoria automáticamente e inicializan campos. C no tiene una característica así, pero podemos simularla con un patrón sencillo: una función create_.
Una función constructora en C normalmente hace tres cosas: asigna memoria con malloc, inicializa todos los campos con los valores adecuados y devuelve un puntero al nuevo objeto:
typedef struct {
char *name;
int age;
} Person;
Person *create_person(const char *name, int age) {
Person *p = malloc(sizeof(Person));
p->name = malloc(strlen(name) + 1);
strcpy(p->name, name);
p->age = age;
return p;
}
La función devuelve un puntero porque el objeto vive en el montón, no en la pila. Esto significa que persiste después de que la función retorna y se puede pasar libremente. La persona que llama lo utiliza así:
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
Observa cómo el constructor gestiona todos los detalles complejos: asignar memoria para la estructura, asignar espacio para la cadena y copiar los datos. El código que realiza la llamada solo proporciona los valores iniciales y recibe un objeto listo para usar. Esto encapsula la lógica de creación en un solo lugar, lo que hace que tu código sea más limpio y menos propenso a errores.
Desafío
FácilConstruyamos un módulo Book que use el patrón constructor para crear objetos de libro en el heap. Practicarás cómo escribir una función create_ que gestione toda la asignación e inicialización de memoria y devuelva un puntero listo para usar.
Crearás tres archivos:
book.h: Declara una estructuraBookcon dos miembros:char *title(un puntero a una cadena asignada dinámicamente) yint pages. Declara también una función constructoracreate_bookque recibe una cadena con el título y el número de páginas, y después devuelve un puntero a un Book recién creado. Usa protecciones contra inclusiones múltiples con el símboloBOOK_H.book.c: Implementa la funcióncreate_book. Tu constructor debe asignar memoria para la propia estructura Book y después asignar memoria separada para la cadena del título (recuerda tener en cuenta el terminador nulo), copiar el título en la nueva memoria, establecer el campo pages y devolver el puntero al nuevo Book.main.c: Usa tu constructor para crear un libro y mostrar su información.
Recibirás dos entradas: el título del libro (una cadena) y el número de páginas (un entero).
En tu archivo principal, usa create_book para crear un libro nuevo con los valores proporcionados y después imprime su información con este formato:
Title: {title}
Pages: {pages}Por ejemplo, con las entradas The C Programming Language y 272, la salida sería:
Title: The C Programming Language
Pages: 272Recuerda que tu constructor encapsula toda la lógica de creación: el código que lo llama simplemente proporciona los valores iniciales y recibe un objeto completamente inicializado y listo para usar.
Pruébalo tú mismo
#include <stdio.h>
#include <stdlib.h>
#include "book.h"
int main() {
char title[256];
int pages;
// Leer entrada
fgets(title, sizeof(title), stdin);
// Eliminar el salto de línea si está presente
for (int i = 0; title[i]; i++) {
if (title[i] == '\n') {
title[i] = '\0';
break;
}
}
scanf("%d", &pages);
// TODO: Usa create_book para crear un nuevo libro con los valores proporcionados
// TODO: Imprime la información del libro en el formato requerido:
// Title: {title}
// Pages: {pages}
// TODO: No olvides liberar la memoria asignada cuando termines
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