Menu
Coddy logo textTech

Incorporação de Structs

Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 28 de 61.

Em linguagens orientadas a objetos como C++ ou Java, a herança permite que uma classe adquira propriedades de uma classe pai. C não possui herança nativa, mas podemos simulá-la usando uma técnica chamada composição — colocando uma struct dentro de outra.

A ideia é simples: se um Child precisa de todas as propriedades de um Parent, incorporamos a struct Parent como um membro de Child.

typedef struct {
    int id;
    char name[50];
} Parent;

typedef struct {
    Parent parent;  // Estrutura incorporada
    int grade;
} Child;

Aqui, Child contém tudo o que Parent tem, além de seu próprio campo grade. Isso é composição — o filho "tem um" pai em vez de "ser um" pai, mas o efeito é semelhante à herança.

Para acessar os membros do pai através de uma instância filha, você usa o operador ponto duas vezes:

Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;

Este padrão forma a base para a construção de hierarquias de tipos em C. Ao incorporar uma struct base como o primeiro membro, desbloqueamos técnicas poderosas que exploraremos nas próximas lições.

challenge icon

Desafio

Fácil

Vamos construir um sistema simples de gerenciamento de funcionários que demonstra a incorporação de structs — a base da herança em C.

Você criará uma hierarquia onde um Employee contém um Person. Isso reflete como a herança funciona: um funcionário "é uma" pessoa com informações adicionais relacionadas ao trabalho. Ao incorporar a struct Person dentro de Employee, você obtém todas as propriedades da pessoa mais os campos específicos do funcionário.

Você organizará seu código em três arquivos:

  • types.h: Defina ambas as structs aqui com guards de inclusão. Primeiro, crie uma struct Person com dois campos: name (um array de caracteres de 50 caracteres) e age (um inteiro). Em seguida, defina uma struct Employee que incorpora Person como seu primeiro membro e adiciona um campo employee_id (um inteiro).
  • types.c: Implemente uma função chamada print_employee que recebe um ponteiro para um Employee e imprime suas informações. Acesse os dados da pessoa incorporada usando a sintaxe encadeada de ponto/seta que você aprendeu.
  • main.c: Crie uma variável Employee, preencha todos os seus campos (incluindo o nome e a idade da pessoa incorporada) e use sua função de impressão para exibir as informações.

Você receberá três entradas: o nome do funcionário (uma string), sua idade (um inteiro) e seu ID de funcionário (um inteiro).

Sua função print_employee deve exibir as informações do funcionário neste formato:

Employee: Alice
Age: 28
ID: 1001

Onde Alice é o nome, 28 é a idade e 1001 é o ID do funcionário das suas entradas.

Lembre-se de acessar os membros da struct incorporada através do membro pai — por exemplo, para chegar ao nome, você navegará pelo membro person primeiro.

Folha de consulta

C não possui herança nativa, mas você pode simulá-la usando composição — incorporando uma struct dentro de outra.

Para criar uma relação pai-filho, incorpore a struct pai como um membro da struct filha:

typedef struct {
    int id;
    char name[50];
} Parent;

typedef struct {
    Parent parent;  // Embedded struct
    int grade;
} Child;

A struct filha contém todas as propriedades da pai, além de seus próprios campos adicionais. Isso representa uma relação do tipo "tem um" (has a).

Para acessar os membros da struct incorporada, use o operador de ponto duas vezes:

Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;

Ao trabalhar com ponteiros, use o operador de seta para acessar os membros da struct incorporada:

Child *ptr = &c;
ptr->parent.id = 101;
ptr->grade = 5;

Incorporar a struct base como o primeiro membro é um padrão comum que permite técnicas avançadas para construir hierarquias de tipos em C.

Experimente você mesmo

#include <stdio.h>
#include <string.h>
#include "types.h"

int main() {
    // Ler entrada
    char name[50];
    int age;
    int employee_id;
    
    fgets(name, 50, stdin);
    name[strcspn(name, "\n")] = '\0';  // Remover nova linha
    scanf("%d", &age);
    scanf("%d", &employee_id);
    
    // TODO: Criar uma variável Employee
    
    // TODO: Preencher o nome e a idade da pessoa incorporada
    // Dica: Use strcpy para o nome, acesse com employee.person.name
    
    // TODO: Definir o employee_id
    
    // TODO: Chamar print_employee com um ponteiro para o seu employee
    
    return 0;
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming