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

Asked

Viewed 672 times

4

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

I am developing a work for college where I need to register students, disciplines and grades and at 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 code of the Discipline 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

Cadastro Alunos

#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

Cadastro Notas

#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 there is a need to implement a function that by excluding a student from the student vector that is in the class Enrollment Students also have to delete all registered grades for this same student, but the grades are in a vector within another class, the Register Notes class. I can exclude the student and grades separately because in each class I have an exclude function, but from within the Student Register class I cannot delete the grades in the Register Grades class.

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

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 file Students.cpp in which I have my functions for Student Class and Student Registration, I can get the vector information but I can’t change it. If I call it inside the.cpp notes where are my functions referring to the notes it erases the notes correctly.

How should I proceed so that I can call from within my Students.cpp this function and it erases the data from the array of notes that is in the Register Grades class?

If you don’t understand anything or need more information and just say.

Thanks again!

EDIT >>>>>>>>>>>>>>>>>>>>>>>

I solved the problem as I commented below only that my "delete" function that I thought was 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);
}

The following happens:

In my note array, I have in each position the matricule, nameName, codeDiscipline, nameDiscipline, media1..., this function would have to scan the entire vector and where the matricule was equal to the searched one ("searchMatricula() function" just below) it would copy the information from the following positions a position above and decrease my index, and re-search if there is still another position with the matricula (I can have more of a registered discipline and registered note for each matricula).

It excludes all notes from the searched matricula, but the other matriculas get duplicate data.

For example I have 2 students/matriculas with 3 disciplines with registered grades for each one (6 positions of the occupied grade vector), if I exclude the student/enrollment 1 it excludes all information but the student/enrollment 2 gets two repeated grades and the last registered grade goes missing, and 4 positions are occupied where they should be only 3.

If anyone finds where I’m going wrong, I’ve made several changes but they all generate the same results or very similar.

Search License plate:

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

EDIT 2 >>>>>>>>>>>>>>>>>>>>>

I solved the problem of the function "delete Otas()" after a lot of breaking the head; I think it is correct now (at least in my tests was working), if anyone finds any error comment q I beg to stay here as reference 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--;
        }
    }
}

Thank you all very much!!!

  • I was able to partially solve the problem, I changed my function from "void excluirAluno()" to "int excluirAluno()" returning me after the student deleted the number of the matricula and inside the file Menu.cpp where are all the menus I use in the program, in the reference case I called two functions to "excluirAluno()" which returns the matricula that I use in "excluirNotas(matricula)".

1 answer

3


The implementation is excellent, but this is a design problem. You have the option to use composition or inheritance. Using composition, the Student class could have Note objects. Therefore, to register or delete, you would do it directly from the Student class (As every Student keeps Note objects, just create accessor and mutator methods agreement). For this case, the composition approach is more appropriate than that of inheritance.

What I want you to do is philosophize about your project. Student and Enrollstudent, Grade and Enrollment Grades? Wouldn’t it be better, Grade, Student and Class? All Student has Note(s), Entire Room has Student(s), and every School/University has Hall(s) (or all "Discipline", in your case). Designing this way, it would be easy to do what you want (Delete a student and their grades at the same time, since by deleting a student, your grades would be automatically deleted. By excluding a classroom, students would be automatically excluded. By excluding a school/university or discipline, all classrooms with all students and all their grades would be automatically excluded).

>>> EDIT:

At Luiz’s request, I will complement the reply.

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

Solving the OP problem with an example in the file main.cpp, upon 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

room. 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

pupil. 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();
}

cpp room.

#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();
}

cpp student.

#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();
}

note.cpp

#include "nota.h"

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

CONCLUSION:

As the OP can see, instead of me including a registration number within the Student class, I created a map within Hall, whose keys are license plates (Thus, it is possible to access every student by their enrollment, without including any enrollment within the Student itself, since this is a detail relevant only to the Classroom). 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 implemented getters and setters accordingly, and most importantly: When you delete a student, your grades are automatically deleted because your grades are part of the Student class, rather than being separated from it.

Anyway, I hope it’s clear how composition solves your problem, and how it’s a design problem (It is even possible to solve your problem without changing the design, but this would be an astronomical atrocity at the project level (It would be possible, if Enrollstudent Enrollment inherited from Enrollment. Thus, it would be possible to exclude grades from within your Students.cpp)).

  • 1

    Great answer. I very much agree with your suggestion. But, maybe the AP has difficulty understanding what you just said by text. If you have a little time, make two dry UML diagrams (one before and one after) to illustrate what you meant. It would also be interesting for you to rework the exclusion method to facilitate this understanding. Such an answer would be great to help not only AP, but other future users with similar questions. :)

  • 1

    All right, @Luizvieira, it’s edited.

  • Thank you very much for the reply, will be preferred this page here for use in future work because this will not have time to change all following your guidelines. I was able to partially solve the problem, I changed my function from "void excluirAluno()" to "int excluirAluno()" returning me after the student deleted the number of the matricula and inside the file Menu.cpp where are all the menus I use in the program, in the reference case I called two functions to "excluirAluno()" which returns the matricula that I use in "excluirNotas(matricula)". But I’m having another problem that I asked the question.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.