Recapitulação - Sistema de Registros de Alunos
Parte da seção Programação Orientada a Objetos do Journey de C++ da Coddy — lição 39 de 104.
É hora de colocar seu conhecimento de encapsulamento em prática! Neste desafio, você construirá um Sistema de Registros de Alunos que demonstra o uso adequado de especificadores de acesso, ocultação de informações e classes aninhadas.
Seu sistema gerenciará os dados dos alunos com estes princípios de encapsulamento:
- Membros de dados privados para proteger informações sensíveis como notas e IDs de alunos
- Interface pública com getters e setters controlados
- Uma classe aninhada para representar notas de cursos individuais, mantendo este detalhe de implementação contido dentro da classe do aluno
Aqui está a estrutura que você implementará:
class Student {
public:
class Grade { // Classe aninhada para notas de cursos
// ...
};
// Interface pública para interagir com os dados do aluno
private:
std::string name;
int studentId;
// Coleção de notas
};Este desafio combina tudo deste capítulo: escolher níveis de acesso apropriados, ocultar detalhes de implementação atrás de uma interface limpa e usar classes aninhadas para organizar tipos relacionados. Pense cuidadosamente sobre o que deve ser acessível e o que deve permanecer oculto.
Desafio
FácilVamos construir um Sistema de Registros de Estudantes que reúne tudo o que você aprendeu sobre encapsulamento. Você criará um sistema onde os dados dos alunos são devidamente protegidos, as notas são gerenciadas por meio de uma classe aninhada e todas as interações ocorrem por meio de uma interface pública limpa.
Você criará dois arquivos para organizar seu código:
Student.h: Defina uma classeStudentque demonstre o encapsulamento adequado com uma classeGradeaninhada.Sua classe
Gradeaninhada (declarada na seção pública deStudent) deve armazenar um nome de curso (string) e uma pontuação (double). Forneça a ela um construtor que receba ambos os valores e forneça os métodosgetCourseName()egetScore()para acessar os dados. A classeGrademantém seus dados privados — embora esteja aninhada dentro deStudent, ela ainda mantém seu próprio encapsulamento.A classe
Studentdeve ter membros privados para o nome do aluno (string), ID do aluno (int) e uma coleção de ponteirosGrade. Forneça:- Um construtor que receba o nome e o ID do aluno
- Getters
getName()egetStudentId()(ambos const) - Um método
addGrade(const std::string& course, double score)que cria uma novaGradee a adiciona ao registro do aluno (adicione apenas se a pontuação estiver entre 0 e 100 inclusive) - Um método
getAverageGrade()(const) que calcula e retorna a média de todas as notas, ou 0.0 se não houver notas - Um método
displayRecord()(const) que mostra o registro completo do aluno
Não se esqueça de limpar as notas alocadas dinamicamente no destruidor e incluir os "header guards" apropriados.
main.cpp: Leia o nome de um aluno, o ID do aluno e três notas de cursos da entrada. O formato de entrada será de cinco linhas: nome, ID e, em seguida, três linhas, cada uma contendo o nome de um curso e a pontuação separados por um espaço (ex:Math 95.5).Crie um
Studentcom o nome e o ID, adicione todas as três notas e exiba o registro completo.O formato de saída para
displayRecord()deve ser:Student: <name> (ID: <id>) Grades: <course1>: <score1> <course2>: <score2> <course3>: <score3> Average: <average>
Formate todas as pontuações e a média com uma casa decimal usando std::fixed e std::setprecision(1) de <iomanip>. Converta o ID usando std::stoi() e as pontuações usando std::stod().
Este desafio combina membros de dados privados, getters públicos, setters controlados com validação e uma classe aninhada — todos trabalhando juntos para criar um sistema de registros de alunos bem encapsulado.
Folha de consulta
O encapsulamento combina especificadores de acesso, ocultação de informações e classes aninhadas para proteger dados e organizar o código.
Especificadores de Acesso para Proteção de Dados
Use private para membros de dados sensíveis e public para a interface:
class Student {
public:
// Métodos de interface pública
private:
std::string name;
int studentId;
// Outros dados privados
};Classes Aninhadas
Classes aninhadas organizam tipos relacionados dentro de uma classe, mantendo seu próprio encapsulamento:
class Student {
public:
class Grade { // Classe aninhada
private:
std::string courseName;
double score;
public:
Grade(const std::string& course, double s)
: courseName(course), score(s) {}
std::string getCourseName() const { return courseName; }
double getScore() const { return score; }
};
private:
std::vector<Grade*> grades;
};Acesso Controlado com Validação
Os métodos podem validar os dados antes de modificar os membros privados:
void addGrade(const std::string& course, double score) {
if (score >= 0 && score <= 100) {
grades.push_back(new Grade(course, score));
}
}Métodos Const
Marque os métodos que não modificam dados como const:
std::string getName() const { return name; }
double getAverageGrade() const {
// Calcula e retorna a média
}Gerenciamento de Memória
Limpe os objetos alocados dinamicamente no destrutor:
~Student() {
for (Grade* grade : grades) {
delete grade;
}
}Experimente você mesmo
#include <iostream>
#include <string>
#include <sstream>
#include "Student.h"
int main() {
// Ler o nome do estudante
std::string name;
std::getline(std::cin, name);
// Ler o ID do estudante
std::string idStr;
std::getline(std::cin, idStr);
int studentId = std::stoi(idStr);
// Ler três notas de cursos (formato: "CourseName Score")
std::string line1, line2, line3;
std::getline(std::cin, line1);
std::getline(std::cin, line2);
std::getline(std::cin, line3);
// TODO: Analisar cada linha para extrair o nome do curso e a pontuação
// Use std::stod() para converter strings de pontuação em doubles
// TODO: Criar um objeto Student com o nome e o ID
// TODO: Adicionar todas as três notas ao estudante
// TODO: Exibir o registro completo do estudante
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 de OOP
Arquivos ExternosBuild e Compilação em C++Arquivos Header e SourceNamespaces e EscopoIntrodução a OOP em C++Classes vs ObjetosO Ponteiro 'this'Métodos (Funções Membro)Atributos (Membros de Dados)Básico de Ctors e DtorsRecapitulação - Calculadora Simples4Propriedades de Classe
Membros de Instância vs EstáticosGetters e SettersFunções de Membro ConstPalavra-chave MutableMétodos e Variáveis EstáticosFunções e Classes FriendRecapitulação - Gerenciador de Conta Bancária7Herança
Herança BásicaNíveis de Acesso na HerançaOrdem de Chamada de Ctor e DtorSobrescrita de MétodosFunções Virtuais e VTableHerança MúltiplaHerança VirtualRecapitulação - Hierarquia de Funcionários2Gerenciamento de Memória
Memória Stack vs HeapPonteiros e ReferênciasMemória Dinâmica (new/delete)Smart Pointers em C++RAII em C++Recapitulação - Gerenciador de Array Dinâmico5Encapsulamento
Especificadores de Acesso em C++Especificadores de Acesso em DetalhesOcultação de InformaçãoStruct vs ClassClasses Aninhadas e InternasRecapitulação - Sistema de Registros de Alunos8Polimorfismo
Polimorfismo de Compilação vs Tempo de ExecuçãoSobrecarga de FunçõesFunções Virtuais RevisitadasFunções Virtuais PurasClasses AbstratasDesign de Interfaces em C++Dynamic Casting e RTTIRecapitulação - Calculadora de Formas3Construtores e Destrutores
Construtor PadrãoConstrutor ParametrizadoConstrutor de CópiaConstrutor de MovimentaçãoListas de Inicialização do ConstrutorConstrutores DelegadosMergulho Profundo em DestrutoresRegra dos Três / Cinco / ZeroRecapitulação - Classe String6Sobrecarga de Operadores
Introdução à Sobrecarga de OperadoresSobrecarga de Operadores AritméticosSobrecarga de Operadores de ComparaçãoOperadores de StreamSobrecarga do Operador de AtribuiçãoSobrecarga dos Operadores [] e ()Operadores de Conversão de TipoRecapitulação - Classe Matrix9Templates
Templates de FunçãoTemplates de ClasseEspecialização de TemplatesTemplates VariádicosFundamentos de SFINAE e Type TraitsRecapitulação - Container Genérico