Baza danych pracowników - pomoc z zadaniem

0

Witam,
Dostałem kolejne zadanie do zrobienia. Jest to moje pierwsze spotkanie z template więc nie bijcie! :D
Mamy podane main() i do niego mamy dorobić potrzebne klasy tak żeby wszystko działało. Część zadania już działa.
Komentarze dodałem po polsku ale kod będę pisał po angielsku. Po prostu do tłumaczenia profesorowi tak będzie lepiej.
Potrzebuję jeszcze dopisać kod do rzeczy, które zakomentowałem:

*cout - operator << do ostream

*DataBase = NewDatabase - tu jak rozumiem operator= ?

Kod maptemplate.cpp:

#include "maptemplate.h"

int main(void)
{
    typedef unsigned int ID;                            //Identification number of Employee
    map_template<ID,Employee> Database;                 //Database of employees

    Database.Add(761028073,Employee("Jan Kowalski","salesman",28));     //Add first employee: name: Jan Kowalski, position: salseman, age: 28,
    Database.Add(510212881,Employee("Adam Nowak","storekeeper",54));    //Add second employee: name: Adam Nowak, position: storekeeper, age: 54
    Database.Add(730505129,Employee("Anna Zaradna","secretary",32));    //Add third employee: name: Anna Zaradna, position: secretary, age: 32

    //cout << Database << endl;                         //Print databese

    //map_template<ID,Employee> NewDatabase = Database; //Make a copy of database

    Employee* pE;
    pE = Database.Find(510212881);       //Find employee using its ID
    pE->Position = "salesman";          //Modify the position of employee
    pE = Database.Find(761028073);     //Find employee using its ID
    pE->Age = 29;             //Modify the age of employee

    //Database = NewDatabase;    //Update original database

    ///cout << Database << endl;  //Print original database
cout<<"Wszystko dziala"<<endl;
}

kod maptemplate.h:

#include <iostream>
#include <vector>

using namespace std;

//Początek klasy Employee bez template
class Employee
{
private:

public:
    Employee(string Name, string Position, int Age);
    string Name;
    int Age;
    string Position;

};//koniec klasy employee

//Dodanie pól Name, Age, Position
Employee::Employee(string Name, string Position, int Age)
{
    this->Name = Name;
    this->Age = Age;
    this->Position = Position;

}

template <class Key, class T> //template <klucze, dane pracownikow>
class map_template{ 
private:
    vector<Key> keys;   //vector do przechowywania unikalnych kluczy pracowników
    vector<T> content;  //vector do przechowywania danych pracowników
public:
    map_template(){}
    void Add(Key key, T t);
    T* Find(Key key);
}; //koniec klasy map_template

//Dodanie do bazy (Add)
template<class Key, class T>
void map_template <Key, T>::Add(Key key, T t)
{
    keys.push_back(key);
    content.push_back(t);
}
//Szukanie w bazie (Find)
template<class Key, class T>
T* map_template<Key, T>::Find(Key key)
{
    for(unsigned int i = 0; i < keys.size(); i++)
        if (keys[i] == key)
        {
            return &content.at(i);
        }
return nullptr;
}

A zatem pytania :D

  1. Jaki nagłówek powinien być do operatora <<. Z tego co widziałem w google to w niektórych przypkach nagłówek był dosyć długi albo nie widziałem zależności więc potrzebuję wytłumaczenia..
    Co w tym powinienem dopisać / zmienić?
 friend ostream & operator<< (ostream & s, tutaj coś na wejscie);

// będzie trzeba odczytać map_template<ID,Employee> Database

Czy nad tą metodą powinno być też template<class Key, class T> ?

Jak zrobię cout, to zajmę się robieniem NewDatabase tak żeby już widzieć jak DataBase wygląda.
Jak ktoś ma jakieś porady, albo pomysły to proszę o aktywność! :D Będę nagradzał lajkami :) Konstruktywny hejt też zlajkuję :D

1

Do Peruna, pora zacząć używać nowocześniejszych składników C++, a w pierwszej kolejności nowego słowa kluczowego auto jak będziesz definiował operator <<.
Nie zapomnij włączyć w kompilatorze flagę obsługi minimum C++11, inaczej auto nie zadziała

0

samo to, że mam użyć "auto" mi nic nie mówi niestety, bo w operator<< nigdy tego nie używałem. Ucząc się z Tobą używałem go tylko z dwa razy :/

Nagłówek operator << może wyglądać tak?

//operator <<
template <class Key, class T>
ostream& operator << (ostream& out, const map_template<Key, T>& map) 
{
    out << map.Name << map.Position << map.Age;  
    return out;
}

map.Name ani inne rzeczy nie zadziałały, a ślepych prób robiłem wiele. Niestety nie ogarniam jak mam się dostać do danych...

Name, Position i Age są zadeklarowane w klasie Employee. A jeśli dobrze rozumiem, to potem dane tych obiektów są przechowywane w vector<t> content.

czyli najpierw bym chciał wejść do content, a potem do danych pól Name itd.

Mógłby ktoś na szybko wytłumaczyć jak to zrobić?

1

Pogóglaj sobie za frazą "specjalizowanie szablonu klas", możliwe, że operator<< będzie wymagał konkretyzacji map_template'a. Ale generalnie dobrze kombinujesz, ino te znaczki referencji stawiaj jak Swaróg przykazał przy zmiennej.
Co do dobierania się do zmiennych name, age itd to zapomniałeś Bracie, że tam po drodze są wektory content i keys, jako prywatne składniki map_template'a. Wygląda znajomo? Powinno :]

0

Nie bardzo rozumiem co będzie do zrobienia. To co wyczytałem to, że specjalizowanie szablonu polega na robieniu szablonów dla danego typu - string itd. i że wygląda to wtedy tak:

template <>

i że to jest to specjalizowanie szablonu klasy.
Znaczki referencji poprawiłem :)
Co do operator << to jeśli są prywatne to muszę dać friend przed całą metodą operator << czy w jakiś inny sposób to zrobić?
Próbowałem dodawać friend to wyrzucało błąd:

maptemplate.h:60:1   'friend' used outside of class

no to oczywiście chciałem dodać deklarację całego operatora << do klasy. Ale tutaj miałem kolejne problemy:
deklaracja tego powinna wyglądać jakoś tak:

//Nagłówek:
friend ostream& operator << (ostream& out, const map_template<Key, T>& map){}
//Deklaracja 
ostream& operator << (ostream& , tutaj nie wiem co)

No i generalnie to nie ogarniam już coraz bardziej tego wszystkiego. Niby prosty operator << do napisania, a siedzę już ponad godzinę nad tym xd

0

Ktokolwiek może ogarnia ten temat?
Obecny kod:

#include <iostream>
#include <vector>

using namespace std;

template <class Key, class T> //template <klucze, dane pracownikow>
class map_template{ 
private:
    vector<Key> keys;   //vector do przechowywania unikalnych kluczy pracowników
    vector<T> content;  //vector do przechowywania danych pracowników
public:

    map_template(){}
    void Add(Key key, T t);
    T* Find(Key key);
}; //koniec klasy map_template

//Dodanie do bazy (Add)
template<class Key, class T>
void map_template <Key, T>::Add(Key key, T t)
{
    keys.push_back(key);
    content.push_back(t);
}
//Szukanie w bazie (Find)
template<class Key, class T>
T* map_template<Key, T>::Find(Key key)
{
    for(unsigned int i = 0; i < keys.size(); i++)
        if (keys[i] == key)
        {
            return &content.at(i);
        }
return nullptr;
}

//Początek klasy Employee bez template
class Employee
{
private:

public:
    Employee(string Name, string Position, int Age);
    string Name;
    int Age;
    string Position;

};//koniec klasy employee

//Dodanie pól Name, Age, Position
Employee::Employee(string Name, string Position, int Age)
{
    this->Name = Name;
    this->Age = Age;
    this->Position = Position;

}
//operator <<
template<class Key, class T>
ostream &operator << (ostream &out, const map_template<Key, T> &map) {
 out << map.Name << map.Position << map.Age;
    return out;
}

Na samym dole jest kod do operator <<. Musi tutaj zadziałać wypisanie w mainie:

map_template<ID,Employee> Database;                 //Database of employees
\...\
cout << Database << endl;

Obecne errory:

maptemplate.h: In instantiation of ‘std::ostream& operator<<(std::ostream&, const map_template<Key, T>&) [with Key = unsigned int; T = Employee; std::ostream = std::basic_ostream<char>]’:
maptemplate.cpp:12:13:   required from here
maptemplate.h:62:13: error: ‘const class map_template<unsigned int, Employee>’ has no member named ‘Name’
  out << map.Name << map.Position << map.Age;
         ~~~~^~~~
maptemplate.h:62:25: error: ‘const class map_template<unsigned int, Employee>’ has no member named ‘Position’
  out << map.Name << map.Position << map.Age;
                     ~~~~^~~~~~~~
maptemplate.h:62:41: error: ‘const class map_template<unsigned int, Employee>’ has no member named ‘Age’
  out << map.Name << map.Position << map.Age;

Może ktoś ma pomysł jak to wypisać poprawnie?

2

Akurat deklaracja przyjaźni to część, która się udaje:

//deklaracje zapowiadające okazują się być potrzebne, inaczej się rzuca o nieznajomość typów
template <class Key, class T> class map_template; 
template <class Key, class T> ostream& operator<<(ostream &o, const map_template<Key, T> &map);

template <class Key, class T> //template <klucze, dane pracownikow>
class map_template{ 
private:
    vector<Key> keys;   //vector do przechowywania unikalnych kluczy pracowników
    vector<T> content;  //vector do przechowywania danych pracowników

public: 
    map_template(){}

    void Add(Key key, T t);
    T* Find(Key key);

friend ostream& operator<< <> (ostream &out, const map_template<Key, T> &map);
};

tylko z użyciem tego były problemy, cały czas mi wyrzucał błąd że nie ma definicji szablonu dla podanych typów Key i T.

EDIT:
Coś Bracie @wiezaawieza ruszyło w temacie.

EDIT2:
Sukces!
DlaWieży.PNG
Dobra Bracie @wiezaawieza, to najcięższą część, czyli deklarację i definicję wspólnymi siłami z Bratem @kq rozkminiłem. Dalej radź sobie sam, bacz na moje wcześniejsze uwagi.

EDIT3:
W sumie, to nie daliśmy definicji dla operatora<<

template<class Key, class T>
ostream& operator<<(ostream &out, const map_template<Key, T> &map)
{
    out << "dupa";   
    return out;
}
1

Mała podpowiedź @wiezaawieza - jak się wyjmuje jakąś daną z std::vector?

0

Odpowiedź na twoją wskazówkę:
Jeśli chodzi o odczytanie wartości to c++ reference podaje, że robi się to podając indeks danej w nawiasach [].
Czyli u nas by to było content[0] na przykład.
http://www.cplusplus.com/reference/vector/vector/operator[]/

Próbowałem kilka funkcji z c++ reference i większość mi nie zadziałała co prawda ale np. map.content.size() wykazało, że size = 3.
Czyli zapewne Name, Age, Position :D
Do tego próbowałem używać funkcji at() ale niestety nic to nie dało.
Jedynie jeszcze funkcja .data() mi wypisała ładnie adres czy coś ;d

No ale chyba chodzi o [ ]. Próbowałem coś w stylu: map.content[0] żeby sprawdzić co jest w pierwszym elemencie ale no też błędy więc nie wiem :/

Jeszcze jakaś mini podpowiedź chyba potrzebna :D

0

Bardzo dobrze, naprawdę ciepło!
A weź Ty mi powiedz Bracie @wiezaawieza, co dokładnie siedzi w tym konkretnym, stworzonym u Ciebie w main() obiekcie map_template, w wektorze content? :]

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0