Problem with polymorphism and vectors in C ++

0

Hello, I am doing a program in C ++ with OOP and polymorphisms but I have a problem when using vectors, this is what I have of code:

Person class (parent class)

#pragma once
#include <iostream>
#include <string>
using namespace std;
class Persona //clase padre
{
    private:
        string nombre;
        int edad;
    public:
        Persona();
        Persona(string, int);
        string getNombre();
        int getEdad();
        void setNombre(string);
        void setEdad(int);
        virtual void addData();
        virtual void showData();
};
Persona::Persona() {}
Persona::Persona(string _nombre, int _edad)
{
    nombre = _nombre;
    edad = _edad;
}
string Persona::getNombre()
{
    return nombre;
}
int Persona::getEdad()
{
    return edad;
}
void Persona::setNombre(string _nombre)
{
    nombre = _nombre;
}
void Persona::setEdad(int _edad)
{
    edad = _edad;
}
void Persona::addData()
{
    string nombre;
    int edad;
    cin.ignore();
    cout << " NOMBRE : ";
    getline(cin, nombre);
    cout << endl;
    setNombre(nombre);
    cout << " EDAD : ";
    cin >> edad;
    setEdad(edad);
}
void Persona::showData()
{
    cout << " NOMBRE : " << getNombre() << endl;
    cout << " EDAD : " << getEdad() << endl;
}

Employee Class

#pragma once
#include "persona.h"
class Empleado : public Persona //clase padre
{
    private:
        string cargo;
        int sueldo;
    public:
        Empleado();
        Empleado(string, int, string, int);
        string getcargo();
        int getsueldo();
        void setcargo(string);
        void setsueldo(int);
        void addData();
        void showData();
};
Empleado::Empleado(){}
Empleado::Empleado(string _cargo, int _sueldo, string nombre, int edad) : Persona(nombre, edad)
{
    cargo = _cargo;
    sueldo = _sueldo;
}

string Empleado::getcargo()
{
    return cargo;
}
int Empleado::getsueldo()
{
    return sueldo;
}
void Empleado::setcargo(string _cargo)
{
    cargo = _cargo;
}
void Empleado::setsueldo(int _sueldo)
{
    sueldo = _sueldo;
}
void Empleado::addData()
{
    string cargo;
    int sueldo;
    cin.ignore();
    Persona::addData();
    cin.ignore();
    cout << " CARGO : ";
    getline(cin, cargo);
    cout << endl;
    setcargo(cargo);
    cout << " SUELDO : ";
    cin >> sueldo;
    setsueldo(sueldo);
}
void Empleado::showData()
{
    Persona::showData();
    cout << " CARGO : " << getcargo() << endl;
    cout << " SUELDO : " << getsueldo() << endl;
}

Student Class

#pragma once
#include "persona.h"
class Estudiante : public Persona //clase padre
{
private:
    string carrera;
    int notaFinal;
public:
    Estudiante();
    Estudiante(string, int, string, int);
    string getcarrera();
    int getnotaFinal();
    void setcarrera(string);
    void setnotaFinal(int);
    void addData();
    void showData();
};
Estudiante::Estudiante() {}
Estudiante::Estudiante(string _carrera, int _notaFinal, string nombre, int edad) : Persona(nombre, edad)
{
    carrera = _carrera;
    notaFinal = _notaFinal;
}
string Estudiante::getcarrera()
{
    return carrera;
}
int Estudiante::getnotaFinal()
{
    return notaFinal;
}
void Estudiante::setcarrera(string _carrera)
{
    carrera = _carrera;
}
void Estudiante::setnotaFinal(int _notaFinal)
{
    notaFinal = _notaFinal;
}
void Estudiante::addData()
{
    string carrera;
    int notaFinal;
    cin.ignore();
    Persona::addData();
    cin.ignore();
    cout << endl;
    cout << " CARRERA : ";
    getline(cin, carrera);
    cout << endl;
    setcarrera(carrera);
    cout << " NOTA FINAL : ";
    cin >> notaFinal;
    setnotaFinal(notaFinal);
}
void Estudiante::showData()
{
    Persona::showData();
    cout << " CARRERA : " << getcarrera() << endl;
    cout << " NOTA FINAL : " << getnotaFinal() << endl;
}

Class Main

#include "estudiante.h"
#include "empleado.h"
#include <conio.h>
#include <vector>

using namespace std;
int menu() {
    system("cls");
    int op;
    cout << "########################" << endl;
    cout << "##      MENU      ##" << endl;
    cout << "#########################" << endl;

    cout << "1.- Ingreso de datos Estudiante" << endl;
    cout << "2.- Ingreso de datos Empleado" << endl;
    cout << "3.- Salida de datos Estudiante" << endl;
    cout << "4.- Salida de datos Empleado" << endl;
    cout << "0=- Salir" << endl;
    do {
        cout << "Elija una opcion" << endl;
        op = _getch();
    } while (op != '0' && op != '1' && op != '2' && op != '3' && op != '4');
    op = op - 48;
    return op;
}
int main() 
{

    vector <Persona*> persona;
    Estudiante* objEstudiante=new Estudiante();

    Empleado objEmpleado;
    vector <Empleado> employ;

    system("color A");

    int op, flag = 1, i = 0;
    char resp;

    _getch();
    do
    {
        op = menu();
        switch (op)
        {
            case 1: system("cls");
                do
                {
                    objEstudiante->addData();
                    persona.push_back(objEstudiante);
                    cout << "Desea ingresar otro dato (S/N)" << endl;
                    cin >> resp;
                } while (resp == 's' || resp == 'S');
                _getch(); break;
            case 2: system("cls");
                do
                {
                    objEmpleado.addData();
                    employ.push_back(objEmpleado);
                    i++;
                    cout << "Desea ingresar otro dato (S/N)" << endl;
                    cin >> resp;
                } while (resp == 's' || resp == 'S');
                _getch(); break;
            case 3: system("cls");

                    for (size_t j = 0; j < persona.size(); j++) {
                        cout << " \n";
                        persona.at(j)->showData();
                        cout << "----------------------" << endl;

                _getch(); break;

            case 4: system("cls");

                    for (int j = 0; j < i; j++) {
                        cout << " \n";
                        cout << "----------------------" << endl;
                    _getch(); break;
        }
    }while (op);

    return 0;

}

The problem that I have in this case is in the Student class when using vectors I can enter data but at the time of showing the data it only shows me the same data several times

    
asked by Erik Andres 04.10.2018 в 20:01
source

1 answer

0
  

The problem that I have in this case is in the Student class when using vectors I can enter data but at the time of showing the data it only shows me the same data several times

Something, on the other hand, logical and normal, since in the list you are entering, all the time, the same pointer

int main() 
{
  vector <Persona*> persona;
  Estudiante* objEstudiante=new Estudiante(); // <<---

The highlighted line is the only place where an instance of Estudiante is created ... the only thing you do later is to modify the data stored in that pointer and add the pointer to the list.

If you print the memory addresses stored in the pointer you will get something like this:

0x04f5340c
0x04f5340c
0x04f5340c
0x04f5340c
0x04f5340c
...

That is, in the list you are storing the same data repeatedly.

To make the program work, consider creating a new element every time you need it:

        case 1: system("cls");
            do
            {
                Estudiante* estudiante = new Estudiante;
                estudiante ->addData();
                persona.push_back(estudiante );
                cout << "Desea ingresar otro dato (S/N)" << endl;
                cin >> resp;
            } while (resp == 's' || resp == 'S');
            _getch(); break;

Now you could claim that the same thing is not happening to the class Empleado ... when the truth is that the object is only being created once. In this second case the program works because the list stores the objects by value instead of storing pointers. This trivial detail is important because, when adding an element to this list, the program has to create a copy of the object of type Empleado . The copy will be completely autonomous, so its status will not be altered if you later modify the original instance.

You can quickly see native types:

int a = 5;
int b = a; // Copiamos el estado de 'a' en 'b'
a = 7;     // Es obvio que este cambio no afecta a 'b'

And to finish, do not forget that the memory you reserve then you have to release it. That waiting for the program to die so that resources are released is not a custom you want to acquire, believe me.

You have filled the persona list of objects stored in dynamic memory reservations and it is your job to release those reserves when they are no longer needed:

  }while (op);

  for( auto elemento : persona )
    delete elemento;

  return 0;
}
    
answered by 05.10.2018 / 07:47
source