Baza danych pracowników - pomoc z zadaniem

Odpowiedz Nowy wątek
2018-12-05 20:42
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

edytowany 2x, ostatnio: wiezaawieza, 2018-12-05 20:45
Może napisz, co jeszcze nie działa i należy dorobić/przerobić. To co jest pokomentowane? - MasterBLB 2018-12-05 21:15
Nom. Na górze napisałem, że pod to co zakomentowane w main() jeszcze trzeba dodać metody / klasy do .h. Ale głównie najpierw tego operator << chyba bym chciał zrobić - wiezaawieza 2018-12-05 21:19

Pozostało 580 znaków

2018-12-05 21:29
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


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
jak auto ma służyć do dedukcji typu zwrotnego to trzeba włączyć już C++14. :P - Tenonymous 2018-12-05 23:45

Pozostało 580 znaków

2018-12-06 18:06
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ć?

Pozostało 580 znaków

2018-12-06 18:16
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 :]


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 1x, ostatnio: MasterBLB, 2018-12-06 18:17

Pozostało 580 znaków

2018-12-06 19:02
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

Pokaż pozostałe 2 komentarze
A o używaniu gógla to zapomniał? Jazda szukać "c++ overload operator<< for template classes", a nie na gotowe tylko. - MasterBLB 2018-12-06 20:33
ok ~20 min zajęło mi znalezienie informacji i stworzenie wersji kompilowalnej, wypisującej "dupa dupa", zaraz spróbuję się do wektorów dobrać. Do roboty wieża leniu. - MasterBLB 2018-12-06 20:38
A ja szukałem i setki razy już kod zmieniałem :D Nie lenie się :P Z tego co widziałem w google to deklaracja może wyglądać tak samo tylko do niej dorzucić frienda. Tylko, że u mnie wtedy nie deklaracja wywala błędy, że całe Key, T itd są niezadeklarowane. Poszukam jeszcze trochę, a jak nic nie znajdę to zrobię post z błędami i pomysłami, które znalazłem i próbowałem zrobić xd - wiezaawieza 2018-12-06 21:35
Cóż, przyznaję się tutaj do niewiedzy. Nie znam wszystkich niuansów C++, kojarzę tylko mniej więcej obszar w jakim się poruszać - co w 90% wypadków wystarcza abym znalazł co chcę w gógle. Jak nie ma, to mam Opus Magnum C++ Grębosza. Niestety, dziś po raz pierwszy w życiu trafiłem na przypadek, że pomimo grzebania w necie, sprawdzeniu w książce Pana Jerzego to nadal nie ma rozwiązania o.O. Ale mam ostatnią linię obrony, to jest biblioteka Qt wraz z kodami źródłowymi. Jak i tam nie znajdę natchnienia przyznam się do porażki. Więc oddalam zarzut o leniwienie się. - MasterBLB 2018-12-06 21:53
No ale jeśli z tym jest lipa to może zostawmy to bez frienda. Można przenieść vectory do public po prostu i się z tym już nie męczyć? Albo jakiś totalnie inny pomysł? nwm no :/ - wiezaawieza 2018-12-06 23:36

Pozostało 580 znaków

2018-12-06 23:43
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?

edytowany 1x, ostatnio: wiezaawieza, 2018-12-06 23:44

Pozostało 580 znaków

2018-12-07 08:20

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;
}

"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 5x, ostatnio: MasterBLB, 2018-12-07 15:13
Pokaż pozostałe 5 komentarzy
Meh, zrobiłeś to samo. Po przeniesieniu definicji operatora nad klasę to się kompiluje. Zła godzina żebym teraz rozmyślał czy to problem (starego?) kompilatora, czy standard tak każe - kq 2018-12-07 08:34
Hej, chwila. Twoja fwd deklaracja nie jest dobra (a raczej definicja jest zła) - jedno ma const map&, a drugie map&. Po poprawie wszystko działa jak powinon - kq 2018-12-07 08:37
O fakt, rzeczywiście! Dzięki Bracie. To teraz ino sprawdzić, czy się do wektorów da radę dobrać. - MasterBLB 2018-12-07 08:42
Ale post trzeba w takim razie poprawić - MasterBLB 2018-12-07 08:44
Właśnie wróciłem i zaraz muszę lecieć do dentysty ale kod u siebie poprawiłem. Co do dobrania się do wektorów to mam nadzieję, że coś wymyślę do północy ;D Dzięki wielkie za poświęcenie czasu! :D Dam znać jak coś się uda :D - wiezaawieza 2018-12-07 15:19

Pozostało 580 znaków

2018-12-07 20:09
1

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


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]

Pozostało 580 znaków

2018-12-07 21:33
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

Pozostało 580 znaków

2018-12-07 21:43
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? :]


"Sugeruję wyobrazić sobie Słońce widziane z orbity Merkurego, a następnie dupę tej wielkości. W takiej właśnie dupie specjalista ma teksty o wspaniałej atmosferze, pracy pełnej wyzwań i tworzeniu innowacyjnych rozwiązań. Pracuje się po to, żeby zarabiać, a z resztą specjalista sobie poradzi we własnym zakresie, nawet jeśli firma mieści się w okopie na granicy obu Korei."
-somekind,
konkretny człowiek-konkretny przekaz :]
edytowany 1x, ostatnio: MasterBLB, 2018-12-07 21:43

Pozostało 580 znaków

2018-12-07 22:26
0

No jest ID i Employee
W tym:
Employee rozdziela się na 3 pola:
Age, Name i Position

Ale samo ID jest z tego drugiego wektora keys, bo to te unikalne wartości pracowników, jakkolwiek to rozumieć ;d

Ale zapis map.content.Employee i coś tam dalej raczej nie zadziała nie?

Pozostało 580 znaków

Odpowiedz
Liczba odpowiedzi na stronę

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