Delete information from a vector that is in another C ++ class

4

Hello, I have a question regarding classes in C ++, I hope someone can help me. Thanks in advance!

I'm developing a college assignment where I need to enroll students, subjects, and grades, and in the end display some reports, all using the concept of classes and object orientation. The program is 99% ready I only found problems to implement the following:

I have 6 classes implemented (I will not post the Discipline code because it is not the case):

Students

#ifndef ALUNOS_HPP_INCLUDED
#define ALUNOS_HPP_INCLUDED

#include "Bibliotecas.hpp"

class Aluno {
public:
    Aluno();

    string nome;
    string cpf;
    string bairro;
    string cidade;
    string endereco;
    string identidade;
    string estadoCivil;
    string dataNascimento;
    int numeroMatricula;
};

#endif // ALUNOS_HPP_INCLUDED

Student Registration

#ifndef CADASTROALUNOS_HPP_INCLUDED
#define CADASTROALUNOS_HPP_INCLUDED

#include "Alunos.hpp"
#include "CadastroNotas.hpp"

//class CadastroNotas;

class CadastroAlunos {
public:
    CadastroNotas cadNotas;

    Aluno alunos[100];
    int indice;

    CadastroAlunos() {indice = 0;}

    void cadastrarAlunos();
    void alterarAlunos();
    void excluirAlunos(CadastroNotas cadNotas);
    void listarAlunos();
    int pesquisar(int numMatricula);
};

#endif // CADASTROALUNOS_HPP_INCLUDED

Notes

#ifndef NOTAS_HPP_INCLUDED
#define NOTAS_HPP_INCLUDED

#include "Bibliotecas.hpp"
class Nota {
public:
    Nota();

    int codigoNota;
    int codigoMatricula;
    int codigoDisciplina;
    double media1;
    double media2;
    double media3;
    double media4;
    double mediaFinal;
    string nomeAluno;
    string nomeDisciplina;
};

#endif // NOTAS_HPP_INCLUDED

Registration Notes

#ifndef CADASTRONOTAS_HPP_INCLUDED
#define CADASTRONOTAS_HPP_INCLUDED

#include "Notas.hpp"
//#include "CadastroAlunos.hpp"
#include "CadastroDisciplinas.hpp"

class CadastroAlunos;

class CadastroNotas {
public:
    //CadastroAlunos cadAlunos;
    CadastroDisciplinas cadDisciplinas;

    Nota notas[100];
    int indice;

    CadastroNotas() {indice = 0;}

    void cadastrarNotas(CadastroAlunos cadAlunos, CadastroDisciplinas cadDisciplinas);
    void alterarNotas();
    void excluirNotas();
    void listarNotas();
    void excluirNotas(int numMatricula);
    int pesquisarMatricula(int pos);
    int pesquisarDisciplina(int pos);
    int comparaPosicao(int matricula, int disciplina);
    string aprovado_reprovado(int pos);
};

#endif // CADASTRONOTAS_HPP_INCLUDED

In them I declare my vectors, the variables I have within each vector and the prototypes of the functions.

The program works 100%, but it is necessary to implement a function that when deleting a student from the student vector that is in the Student Master class, I also have to delete all the notes registered for this same student, but the notes are in a vector inside of another class, the Notes Master class. I can exclude the student and the notes separately because in each class I have a delete function, but from within the Student Master class I can not delete the notes in the Master Notes class.

My function to delete notes (It is in Notes.cpp where my notes functions are):

void CadastroNotas::excluirNotas(int numMatricula) {
    int pos = 0;
    do {
        pos = pesquisarMatricula(numMatricula);
        if(pos >= 0){
            for(int i = pos; i < indice; i++) {
                notas[pos] = notas[pos + 1];
                indice--;
            }
        }
    } while(pos >= 0);
}

I call this function in my Student.cpp file where I have my functions for Student and Student Class, I can get the information from the vector but I can not change it. If I call it inside the Notes.cpp where my notes functions are, it erases the notes correctly.

How do I get this function to call from within my Student.cpp and delete it from the note vector that is in the Notes Master class?

If you do not understand something or need more information and just say.

Thanks again!

EDIT> EDIT> EDIT ; >

I solved the problem as I mentioned below only that my "deleteNotes ()" function that I found to be working correctly is not.

void CadastroNotas::excluirNotas(int numMatricula) {
    int pos = 0;
    do {
        pos = pesquisarMatricula(numMatricula);
        if(pos >= 0){
            for(int i = pos; i < indice; i++) {
                notas[pos] = notas[pos + 1];
            }
            indice--;
        }
    } while(pos >= 0);
}

It happens as follows:

In my vector of notes I have in each position the registration, nameAluno, codeDisciplina, nombreDisciplina, media1 ..., this function would have to scan the entire vector and where the registration was equal to the searched one (function "searchMatricula ()" logo below) would copy the information from the following positions to a position above and would decrease my index, and I would re-search if there is still another position with the enrollment (I can have more than one registered subject and one registered note for each enrollment).

It excludes all notes from the enrolled enrollment, but other enrollments have duplicate data.

For example, I have 2 students with 3 subjects with notes registered for each one (6 positions of the vector of occupied notes), if I have to exclude the student 1, he excludes all the information but the student 2 with two repeated notes and the last recorded note goes out, and there are 4 occupied positions where they should be only 3.

If someone finds where I am wrong, I have made several changes but all generate the same or very similar results.

Search Enrollment:

int CadastroNotas::pesquisarMatricula(int pos) {
    for(int i = 0; i < indice; i++) {
        if (notas[i].codigoMatricula == pos)
            return i;
    }
    return -1;
}

EDIT 2> EDIT 2> EDIT 2

I solved the problem of the "deleteNotes ()" function after a lot of head breaking; I think it's correct now (at least in my tests it was working), if anyone finds any errors, I'll comment on them for future research.

void CadastroNotas::excluirNotas(int numMatricula) {
    for(int i = 0; i < indice; i++) {
        if(notas[i].codigoMatricula == numMatricula) {
            for(int j = i; j < indice; j++) {
                notas[j] = notas[j + 1];
            }
            i--;
            indice--;
        }
    }
}

Many thanks to all!

    
asked by anonymous 29.06.2015 / 04:04

1 answer

3

The implementation is fine, but this is a design problem. You have the option to use composition or inheritance . Using composition, the Student class could have Note objects. So, to register or delete, you would do so directly from the Student class (Because every Student keeps Note objects, you only have to create accessor and mutator methods accordingly). For this case, the composition approach is more appropriate than inheritance.

What I want you to do is to philosophize about your project. Student and Student Registration, Note and RegistrationNotes? Would not it be better, Grade, Student and Room? All Student has Note (s), every Room has Student (s), and every School / University has Room (s) (or any "Discipline" ). By designing this way, it would be easy to do what you want (Exclude a student and his grades at the same time, since when you delete a student, your grades would be deleted automatically. / university or discipline, all rooms with all students and all their grades, would be automatically deleted.)

> > > EDIT:

At the request of Luiz, I will complement the answer.

I re-created the OP project in 9 files (4 headers, and 5 source files).

Solving the OP problem with an example in the main.cpp file, above my implementation:

#include "disciplina.h"
#include "sala.h"
#include "aluno.h"
#include "nota.h"

#include <iostream>

int main(int argc, char **argv)
{
    Disciplina matematica("Matematica");

    // Cadastramento de Salas por Número.

    matematica.cadastrar_sala(1, Sala());
    matematica.cadastrar_sala(2, Sala());

    Sala primeira_sala = matematica.pegar_sala(1);
    Sala segunda_sala = matematica.pegar_sala(2);

    // Cadastramento de Alunos por Matrícula.

    primeira_sala.cadastrar_aluno(11, Aluno("Isabelle"));
    primeira_sala.cadastrar_aluno(22, Aluno("Victoria"));
    segunda_sala.cadastrar_aluno(33, Aluno("Agatha"));
    segunda_sala.cadastrar_aluno(44, Aluno("Annabel Lee"));

    Aluno al1 = primeira_sala.pegar_aluno(11);
    Aluno al2 = primeira_sala.pegar_aluno(22);
    Aluno al3 = segunda_sala.pegar_aluno(33);
    Aluno al4 = segunda_sala.pegar_aluno(44);

    // Cadastramento de Notas por Código.

    al1.cadastrar_nota(6666, Nota());
    al2.cadastrar_nota(7777, Nota());
    al3.cadastrar_nota(8888, Nota());
    al4.cadastrar_nota(9999, Nota());

    /*

    Resolução do Problema do OP.

    Victoria foi uma aluna muito, muito ruim,
    E por tanto, foi excluída da sala, e junto com ela,
    Todas as suas notas...

    */

    primeira_sala.excluir_aluno(22); // Excluir por matrícula.
    cout << primeira_sala.pegar_quantidade_de_alunos(); // Confirmar que agora, na primeira sala, há apenas 1 aluno (Isabelle).

    return EXIT_SUCCESS;
}

IMPLEMENTATION:

  • Headers

Discipline.h

#ifndef DISCIPLINA_H_INCLUDED
#define DISCIPLINA_H_INCLUDED

#include "sala.h"

typedef int numero;

class Disciplina
{
private:
    string nome;
    map<numero, Sala> salas;
public:
    Disciplina(string nome);
    ~Disciplina() {};
    string pegar_nome();
    map<numero, Sala> pegar_salas();
    Sala pegar_sala(numero n);
    void alterar_nome(string nome);
    int pegar_quantidade_de_salas();
    void cadastrar_sala(numero n, Sala sala);
    void excluir_sala(numero n);
    bool checar_se_ha_sala(numero n);
    void excluir_todas_as_salas();
};

#endif // DISCIPLINA_H_INCLUDED

sala.h

#ifndef SALA_H_INCLUDED
#define SALA_H_INCLUDED

#include "aluno.h"

typedef int matricula;

class Sala
{
private:
    map<matricula, Aluno> alunos;
public:
    Sala() {};
    ~Sala() {};
    map<matricula, Aluno> pegar_alunos();
    Aluno pegar_aluno(matricula m);
    int pegar_quantidade_de_alunos();
    void cadastrar_aluno(matricula m, Aluno aluno);
    void excluir_aluno(matricula m);
    bool checar_se_ha_aluno(matricula m);
    void excluir_todos_os_alunos();
};

#endif // SALA_H_INCLUDED

student.h

#ifndef ALUNO_H_INCLUDED
#define ALUNO_H_INCLUDED

#include "nota.h"

typedef int codigo;

class Aluno
{
private:
    string nome;
    string cpf;
    string bairro;
    string cidade;
    string endereco;
    string identidade;
    string estado_civil;
    string data_de_nascimento;
    map<codigo, Nota> notas;
public:
    Aluno(
        string nome="",
        string cpf="",
        string bairro="",
        string cidade="",
        string endereco="",
        string identidade="",
        string estado_civil="",
        string data_de_nascimento="");
    ~Aluno() {};
    string pegar_nome();
    string pegar_cpf();
    string pegar_bairro();
    string pegar_cidade();
    string pegar_endereco();
    string pegar_identidade();
    string pegar_estado_civil();
    string pegar_data_de_nascimento();
    map<codigo, Nota> pegar_notas();
    Nota pegar_nota(codigo n);
    int pegar_quantidade_de_notas();
    void alterar_nome(string nome);
    void alterar_cpf(string cpf);
    void alterar_bairro(string bairro);
    void alterar_cidade(string cidade);
    void alterar_endereco(string endereco);
    void alterar_identidade(string identidade);
    void alterar_estado_civil(string estado_civil);
    void alterar_data_de_nascimento(string data_de_nascimento);
    void cadastrar_nota(codigo n, Nota nota);
    void excluir_nota(codigo n);
    bool checar_se_ha_nota(codigo n);
    void excluir_todas_as_notas();
};

#endif // ALUNO_H_INCLUDED

Note.h

#ifndef NOTA_H_INCLUDED
#define NOTA_H_INCLUDED

#include <string>
#include <map>
using namespace std;

class Nota
{
private:
    double media1;
    double media2;
    double media3;
    double media4;
    double media_final;
public:
    Nota() {};
    ~Nota() {};
    /*
    Métodos de cálculo de média aqui.
    */
};

#endif // NOTA_H_INCLUDED
  • Source Files

Discipline.cpp

#include "disciplina.h"

Disciplina::Disciplina(string nome)
{
    this->nome = nome;
}

string Disciplina::pegar_nome()
{
    return this->nome;
}

map<numero, Sala> Disciplina::pegar_salas()
{
    return this->salas;
}

void Disciplina::alterar_nome(string nome)
{
    this->nome = nome;
}

Sala Disciplina::pegar_sala(numero n)
{
    return this->salas[n];
}

int Disciplina::pegar_quantidade_de_salas()
{
    return this->salas.size();
}

void Disciplina::cadastrar_sala(numero n, Sala sala)
{
    this->salas[n] = sala;
}

void Disciplina::excluir_sala(numero n)
{
    this->salas.erase(n);
}

bool Disciplina::checar_se_ha_sala(numero n)
{
    if (this->salas.count(n) > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

void Disciplina::excluir_todas_as_salas()
{
    this->salas.clear();
}

sala.cpp

#include "sala.h"

map<matricula, Aluno> Sala::pegar_alunos()
{
    return this->alunos;
}

Aluno Sala::pegar_aluno(matricula m)
{
    return this->alunos[m];
}

int Sala::pegar_quantidade_de_alunos()
{
    return this->alunos.size();
}

void Sala::cadastrar_aluno(matricula m, Aluno aluno)
{
    this->alunos[m] = aluno;
}

void Sala::excluir_aluno(matricula m)
{
    this->alunos.erase(m);
}

bool Sala::checar_se_ha_aluno(matricula m)
{
    if (this->alunos.count(m) > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

void Sala::excluir_todos_os_alunos()
{
    this->alunos.clear();
}

aluno.cpp

#include "aluno.h"

Aluno::Aluno(
    string nome,
    string cpf,
    string bairro,
    string cidade,
    string endereco,
    string identidade,
    string estado_civil,
    string data_de_nascimento)
{
    this->nome = nome;
    this->cpf = cpf;
    this->bairro = bairro;
    this->cidade = cidade;
    this->endereco = endereco;
    this->identidade = identidade;
    this->estado_civil = estado_civil;
    this->data_de_nascimento = data_de_nascimento;
}

string Aluno::pegar_nome()
{
    return this->nome;
}

string Aluno::pegar_cpf()
{
    return this->cpf;
}

string Aluno::pegar_bairro()
{
    return this->bairro;
}

string Aluno::pegar_cidade()
{
    return this->cidade;
}

string Aluno::pegar_endereco()
{
    return this->endereco;
}

string Aluno::pegar_identidade()
{
    return this->identidade;
}

string Aluno::pegar_estado_civil()
{
    return this->estado_civil;
}

string Aluno::pegar_data_de_nascimento()
{
    return this->data_de_nascimento;
}

map<int, Nota> Aluno::pegar_notas()
{
    return this->notas;
}

Nota Aluno::pegar_nota(codigo n)
{
    return this->notas[n];
}

int Aluno::pegar_quantidade_de_notas()
{
    return this->notas.size();
}

void Aluno::alterar_nome(string nome)
{
    this->nome = nome;
}

void Aluno::alterar_cpf(string cpf)
{
    this->cpf = cpf;
}

void Aluno::alterar_bairro(string bairro)
{
    this->bairro = bairro;
}

void Aluno::alterar_cidade(string cidade)
{
    this->cidade = cidade;
}

void Aluno::alterar_endereco(string endereco)
{
    this->endereco = endereco;
}

void Aluno::alterar_identidade(string identidade)
{
    this->identidade = identidade;
}

void Aluno::alterar_estado_civil(string estado_civil)
{
    this->estado_civil = estado_civil;
}

void Aluno::alterar_data_de_nascimento(string data_de_nascimento)
{
    this->data_de_nascimento = data_de_nascimento;
}

void Aluno::cadastrar_nota(codigo n, Nota nota)
{
    this->notas[n] = nota;
}

void Aluno::excluir_nota(codigo n)
{
    this->notas.erase(n);
}

bool Aluno::checar_se_ha_nota(codigo n)
{
    if (this->notas.count(n) > 0)
    {
        return true;
    }
    else
    {
        return false;
    }
}

void Aluno::excluir_todas_as_notas()
{
    this->notas.clear();
}

nota.cpp

#include "nota.h"

/*
Métodos de cálculo de média aqui.
*/

CONCLUSION:

As the OP can see, instead of including a registration number within the Student class, I created a map inside the Room, whose keys are registrations (Thus, it is possible to access all students by their enrollment, without including any enrollment within the Student itself, since this is a relevant detail only for the Hall). The same happens with the Room (Discipline has a map whose keys are numbers), and with Note (Student has a map whose keys are codes for Notes). I've implemented getters and setters accordingly, and most importantly: When deleting a student, their grades are automatically deleted, as the grades are in the Student class, instead they are separated from it.

Anyway, I hope it has become clear how composition solves your problem, and how it is a design problem. (It's even possible to solve your problem without changing the design, but this would be an astronomical atrocity at the level of (It would be possible, if StudentName was inherited from StudentName, so it would be possible to delete the notes from within your Student.cpp)).

    
29.06.2015 / 05:08