Hola compis, estoy inciándome con C++, haciendo cosicas en modo consola y tal...
Se me ha propuesto el siguiente ejercicio. El enunciado está en inglés pero no creo que requiera traducción:
2. Design and implement a Name_pairs class holding (name,age) pairs where name is a string and age is a double.
Represent that as a vector<string> (called name) and a vector<double> (called age) member.
Provide an input operation read_names() that reads a series of names.
Provide a read_ages() operation that prompts the user for an age for each name.
Provide a print() operation that prints out the (name,age) pairs (one per line) in the orderdetermined by the name vector.
Provide a sort() operation that sorts the name vector in alphabetical order and reorganizes the age vector to match.
Implement all “operations” as member functions.
Ok, esto lo puedo hacer sin demasiado problema. Pongo el código a continuación.
Si alguien quiere compilarlo, necesitará esta librería:
std_lib_facilities.h#include "..\..\..\..\lib\std_lib_facilities.h"
namespace Nombres {
class Name_pairs
{
public:
void read_names();
void read_ages();
void print();
void sort();
private:
vector <string> name;
vector <double> age;
};
void Name_pairs::read_names()
{
string nombre;
do
{
cout << "\nIntroduzca nombre(*=FIN): ";
cin >> nombre;
if (nombre != "*") name.push_back(nombre);
} while (nombre != "*");
}
void Name_pairs::read_ages()
{
int t = name.size();
double edad;
if (t == 0)
{
cout << "\nPrimero hay que introducir nombres...\n";
}
else
{
for (int i = 0; i < t; i++)
{
cout << "\nIntroduzca la edad de: " << name[i] << " --> ";
cin >> edad;
age.push_back(edad);
}
}
}
void Name_pairs::print()
{
int t = name.size();
if (t == 0)
{
cout << "\nNo hay datos que mostrar.\n";
}
else
{
for (int i = 0; i < t; i++)
{
cout << "\nNombre: " << name[i] << " Edad: " << age[i];
}
}
}
void Name_pairs::sort()
{
int t = name.size();
if (t == 0)
{
cout << "\nNo hay datos que ordenar.\n";
}
else
{
vector <string> name_temp;
vector <double> age_temp;
for (int i = 0; i < t; i++)
{
name_temp.push_back(name[i]);
age_temp.push_back(age[i]);
}
std::sort(name.begin(), name.end());//Recalco que este sort() pertenece a std, y no a mi clase Name_pairs.
//Busca coincidencias entre los vectores de nombres original y ordenado para "copiar" el mismo orden en el vector de edad.
//Esta funcion podria ser errónea si hubieran nombres repetidos en el vector.
for (int i = 0; i < t; i++)
{
for (int j = 0; j < t; j++)
{
if (name_temp[i] == name[j]) age[j] = age_temp[i];
}
}
}
}
}//namespace Nombres
int main()
{
using namespace Nombres;
cout << system("cls");
Name_pairs listado;
listado.read_names();
listado.read_ages();
listado.print();
listado.sort();
listado.print();
cout << endl;
return 0;
}
Todo esto compila bien y compruebo con un pequeño main() que todo furrula: pide nombres hasta meter un asterisco, puego pide edades para cada nombre, luego los muestra, los ordena alfabéticamente, ordena también el vector edades según se ordenó el vector de nombres y vuelve a mostrarlos tras los cambios.
Ahora viene la segunda parte, que es la que se me atraganta:
3. Replace Name_pair::print() with a (global) operator << and define == and != for Name_pairs.*/
Bien, de momento solo he intentado hacer que el operador
<< haga lo que hace print().... pero no lo consigo.
En print(), lo primero que hago es obtener el tamaño del vector de nombres, para comprobar si hay algo que mostrar y si lo hay, pues lo uso para el contador del bucle.
Intento hacer lo mismo en la funcion donde modifico el operador
<< , pero me da error pues no reconoce el vector name.
/*
//Sustituimos esta funcion con la siguiente donde modificamos el operador <<
void Name_pairs::print()
{
int t = name.size();
if (t == 0)
{
cout << "\nNo hay datos que mostrar.\n";
}
else
{
for (int i = 0; i < t; i++)
{
cout << "\nNombre: " << name[i] << " Edad: " << age[i];
}
}
}*/
ostream& operator<<(ostream& os, const Name_pairs& np)
{
int t = name.size();
//Falta código por escribir....
}
Vale, tiene sentido, pues no indico a que objeto me refiero y tal.
Pruebo a dar un palo de ciego con esto, que no se por qué, ya imaginaba que tampoco iba a servir:
ostream& operator<<(ostream& os, const Name_pairs& np)
{
int t = np.name.size();
//Falta código por escribir....
}
Y me digo, pues oye, hacemos una nueva funcion en public: que devuelva el tamaño del vector. Que además, es un dato que estoy necesitando en el resto de funciones.
namespace Nombres {
class Name_pairs
{
public:
void read_names();
void read_ages();
void sort();
int name_size();//devuelve el tamaño del vector de nombres
private:
vector <string> name;
vector <double> age;
};
int Name_pairs::name_size()
{
return name.size();
}
[.....]
ostream& operator<<(ostream& os, const Name_pairs& np)
{
int t = np.name_size();
//Falta código por escribir....
}
Y nada, tampoco furrula, obtengo estos errores al compilar:
Error C2662 'int Nombres::Name_pairs::name_size(void)': no se puede convertir el puntero 'this' de 'const Nombres::Name_pairs' a 'Nombres::Name_pairs &' 235_03 e:\programación\c++\consola\libro\235_03\235_03\235_03.cpp 81
Error (activo) el objeto tiene calificadores de tipo que no son compatibles con la función "Nombres::Name_pairs::name_size" miembro 235_03 e:\Programación\C++\Consola\Libro\235_03\235_03\235_03.cpp 81
Y me he quedado sin ideas....
Si el parámetro
np se supone que representa un objeto de clase Name_pairs, ¿donde está el problema? ¿Qué hago mal?
Espero haberme explicado más o menos claro, a ver si podeis guiarme...
Gracias por adelantado