Padrão de construtor
Parte da seção Programação Orientada a Objetos do Journey de C da Coddy. Lição 12 de 61.
Em linguagens como Java ou C++, você cria objetos usando construtores: funções especiais que alocam memória e inicializam campos automaticamente. C não tem esse recurso, mas podemos simulá-lo com um padrão simples: uma função create_.
Uma função construtora em C normalmente faz três coisas: aloca memória com malloc, inicializa todos os campos com os valores adequados e retorna um ponteiro para o novo 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;
}
A função retorna um ponteiro porque o objeto fica no heap, não na pilha. Isso significa que ele persiste depois que a função retorna e pode ser passado livremente. O chamador o usa assim:
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
Observe como o construtor cuida de todos os detalhes complicados: alocar a estrutura, alocar espaço para a string e copiar os dados. Quem faz a chamada apenas fornece os valores iniciais e recebe um objeto pronto para uso. Isso encapsula a lógica de criação em um só lugar, tornando seu código mais limpo e menos sujeito a erros.
Desafio
FácilVamos criar um módulo Book que usa o padrão construtor para criar objetos de livro no heap. Você vai praticar como escrever uma função create_ que cuida de toda a alocação e inicialização da memória e retorna um ponteiro pronto para uso.
Você vai criar três arquivos:
book.h: Declare uma structBookcom dois membros:char *title(um ponteiro para uma string alocada dinamicamente) eint pages. Declare também uma função construtoracreate_bookque recebe uma string com o título e a quantidade de páginas e retorna um ponteiro para um novo objeto Book. Use guardas de inclusão com o símboloBOOK_H.book.c: Implemente a funçãocreate_book. Seu construtor deve alocar memória para a própria struct Book e, em seguida, alocar memória separadamente para a string do título (lembre-se de considerar o terminador nulo), copiar o título para a nova memória, definir o campo pages e retornar o ponteiro para o novo objeto Book.main.c: Use seu construtor para criar um livro e exibir suas informações.
Você receberá duas entradas: o título do livro (uma string) e a quantidade de páginas (um inteiro).
No seu arquivo principal, use create_book para criar um novo livro com os valores fornecidos e, em seguida, imprima suas informações neste formato:
Title: {title}
Pages: {pages}Por exemplo, com as entradas The C Programming Language e 272, a saída seria:
Title: The C Programming Language
Pages: 272Lembre-se de que seu construtor encapsula toda a lógica de criação: quem o chama simplesmente fornece os valores iniciais e recebe um objeto totalmente inicializado e pronto para uso.
Experimente você mesmo
#include <stdio.h>
#include <stdlib.h>
#include "book.h"
int main() {
char title[256];
int pages;
// Leia a entrada
fgets(title, sizeof(title), stdin);
// Remova a quebra de linha, se houver
for (int i = 0; title[i]; i++) {
if (title[i] == '\n') {
title[i] = '\0';
break;
}
}
scanf("%d", &pages);
// TODO: Use create_book para criar um novo livro com os valores fornecidos
// TODO: Imprima as informações do livro no formato exigido:
// Título: {title}
// Páginas: {pages}
// TODO: Não se esqueça de liberar a memória alocada ao terminar
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Programação Orientada a Objetos
1Fundamentos da Programação Modular
Arquivos de cabeçalhoProteções de inclusãoArquivos-fonteFunções estáticasRevisão: calculadora modular4Encapsulamento
Conceito de ponteiros opacosDefinindo structs opacasGetters e settersValidação em settersRevisão: caixa secreta2Objetos e métodos
Structs como objetosO ponteiro 'Self'Correção de constPonteiro vs. valorMétodos auxiliaresRevisão: Gerenciador de pontos5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de vida do objeto
Padrão de construtorPadrão de destrutorInicialização da pilhaCópia profundaRevisão: wrapper de String6Herança por composição
Incorporação de structRegra do primeiro membroAcessando membros do tipo paiUpcastingRevisão: hierarquia de formas9Projeto: Desenhador de Formas
Visão geral do projetoImplementação do círculoImplementação do retânguloUso polimórficoContêiner de formasPratique por conta própria: Compilador de C online