Padrão de Construtor
Parte da seção Object Oriented Programming 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 possui tal 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 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 reside na heap, não na stack. Isso significa que ele persiste após o retorno da função e pode ser passado livremente. O chamador o utiliza desta forma:
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
Observe como o construtor lida com todos os detalhes complicados — alocando a struct, alocando espaço para a string e copiando os dados. O chamador 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 propenso a erros.
Desafio
FácilVamos construir um módulo Book que utiliza o padrão constructor para criar objetos de livro no heap. Você praticará a escrita de uma função create_ que lida com toda a alocação de memória e inicialização, retornando um ponteiro pronto para uso.
Você criará três arquivos:
book.h: Declare uma structBookcom dois membros:char *title(um ponteiro para uma string alocada dinamicamente) eint pages. Também declare uma função construtoracreate_bookque recebe uma string de título e a contagem de páginas, e então retorna um ponteiro para um novo Book criado. Use include guards com o símboloBOOK_H.book.c: Implemente a funçãocreate_book. Seu construtor deve alocar memória para a própria struct Book, depois alocar memória separada 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 de páginas e retornar o ponteiro para o novo 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 o número de páginas (um número 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 — o chamador simplesmente fornece os valores iniciais e recebe um objeto totalmente inicializado pronto para uso.
Folha de consulta
Uma função construtora em C simula a criação de objetos alocando memória e inicializando campos. Ela geralmente segue o padrão de nomenclatura create_.
Uma função construtora faz três coisas:
- Aloca memória com
malloc - Inicializa todos os campos com os valores adequados
- Retorna um ponteiro para o novo objeto
Exemplo de padrão de construtor:
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;
}
Usando o construtor:
Person *alice = create_person("Alice", 30);
printf("%s is %d years old\n", alice->name, alice->age);
A função retorna um ponteiro porque o objeto reside na heap e persiste após o retorno da função. Isso encapsula a lógica de criação em um só lugar, tornando o código mais limpo e menos propenso a erros.
Experimente você mesmo
#include <stdio.h>
#include <stdlib.h>
#include "book.h"
int main() {
char title[256];
int pages;
// Ler entrada
fgets(title, sizeof(title), stdin);
// Remover a quebra de linha se estiver presente
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: Imprimir as informações do livro no formato exigido:
// Title: {title}
// Pages: {pages}
// TODO: Não se esqueça de liberar a memória alocada quando 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 Object Oriented Programming
1Fundamentos da Programação Modular
Arquivos de CabeçalhoInclude GuardsArquivos-FonteFunções EstáticasRecapitulação: Calculadora Modular4Encapsulamento
Conceito de Ponteiros OpacosDefinindo Structs OpacasGetters e SettersValidação em SettersRecapitulação: Caixa Secreta2Objetos e Métodos
Structs como ObjetosO Ponteiro 'Self'Const CorrectnessPonteiro vs ValorMétodos AuxiliaresRecapitulação: Point Manager5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de Vida de Objetos
Padrão de ConstrutorPadrão de DestrutorInicialização na StackCópia ProfundaRecapitulação: String Wrapper6Herança via Composição
Incorporação de StructsA Regra do Primeiro MembroAcessando Membros PaiUpcastingRecapitulação: Hierarquia de Formas9Projeto: Desenhador de Formas
Visão Geral do ProjetoImplementação do Círculo