Acceso a miembros padre
Parte de la sección Programación Orientada a Objetos del Journey de C de Coddy. Lección 30 de 61.
Ahora que entendemos la inclusión de structs y la regla del primer miembro, centrémonos en el aspecto práctico: cómo leer y modificar los datos del parent incluido desde dentro de una función.
Cuando una función recibe una estructura Child (o un puntero a ella), acceder a los miembros de parent requiere navegar a través de la estructura insertada. La sintaxis depende de si trabajas con un valor o un puntero.
typedef struct {
int id;
int score;
} Parent;
typedef struct {
Parent parent;
char grade;
} Child;Con un puntero a Child, usa el operador de flecha para acceder al padre y, después, el punto para acceder a sus miembros:
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // Flecha luego punto
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}Con un valor (pasado por copia), usa puntos en todo momento:
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // Punto luego punto
}Este patrón de acceso encadenado, child->parent.member o child.parent.member, es la forma de interactuar con datos heredados en el modelo de composición de C. Es ligeramente más verboso que la herencia real, pero es explícito y claro acerca de la relación entre los tipos.
Desafío
FácilConstruyamos un sistema de calificaciones de estudiantes que demuestre cómo acceder a los datos dentro de una estructura embebida y modificarlos. Crearás una jerarquía en la que un Student contiene un Person embebido, y después escribirás funciones que trabajen con los datos del padre a través del hijo.
Organizarás tu código en tres archivos:
student.h: Define la jerarquía de tus estructuras con protectores de inclusión. Crea una estructuraPersonconname(un arreglo de caracteres de 50 caracteres) yage(un entero). Después define una estructuraStudentque embebaPersoncomo su primer miembro y añada un campograde(un entero que representa su calificación). Declara dos funciones:set_person_age, que recibe unStudent*y un nuevo valor de edad, yprint_student, que recibe unStudent*y muestra toda la información.student.c: Implementa ambas funciones. Tu funciónset_person_agedebe modificar la edad dentro de la estructuraPersonembebida. Aquí practicarás la sintaxis de flecha seguida de punto (s->person.age). Tu funciónprint_studentdebe acceder a todos los campos, tanto de la persona embebida como del estudiante, y mostrarlos.main.c: Crea una variableStudente inicializa todos sus campos. Después usaset_person_agepara actualizar la edad de la persona embebida y llama aprint_studentpara mostrar el resultado.
Recibirás cuatro entradas: el nombre del estudiante (una cadena), su edad inicial (un entero), su calificación (un entero) y una nueva edad (un entero que se actualizará mediante tu función).
En tu archivo principal, crea el estudiante con los valores iniciales, después llama a set_person_age para cambiar la edad al nuevo valor y, finalmente, llama a print_student para mostrar la información actualizada.
Tu salida debería verse así:
Name: Emma
Age: 21
Grade: 85Donde Emma es el nombre, 21 es la edad actualizada (no la edad inicial) y 85 es la calificación. El aprendizaje clave aquí es recorrer la estructura embebida para leer y escribir los miembros del padre.
Pruébalo tú mismo
#include <stdio.h>
#include <string.h>
#include "student.h"
int main() {
char name[50];
int initial_age, grade, new_age;
// Leer entradas
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // Eliminar salto de línea
scanf("%d", &initial_age);
scanf("%d", &grade);
scanf("%d", &new_age);
// TODO: Crear una variable Student
// TODO: Inicializar todos los campos del student
// - Copiar name al name de la persona embebida usando strcpy
// - Establecer la age de la persona embebida a initial_age
// - Establecer el grade del student
// TODO: Llamar a set_person_age para actualizar la age a new_age
// TODO: Llamar a print_student para mostrar el resultado
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