Polimorfizm + listy dynamiczne.

0

Witam.
Mniej więcej orientuję się na czym polega polimorfizm, oraz jak go zastosować w przypadku gdy tworzymy nowy obiekt w mainie za pomocą jakiegoś konstruktora, a następnie chcemy go np. wyświetlić. Ale nie ważne co, wiem. Nie wiem jak zastosować polimorfizm w przypadku gdy:

  1. Mam 3 klasy: Osoba - klasa bazowa; Student - klasa dziedzicząca; Pracownik - klasa dziedzicząca.

  2. Wczytuję studentów i pracowników z pliku oddzielną funkcją i dodaję ich do jednokierunkowej listy dynam. również 2 funkcjami typu:

 
void dodajp(pracownik* (&glowa), pracownik* dodaj) {
       
    //jeśli głowa nie istnieje
        if(glowa == NULL){
                glowa = dodaj;
                glowa->nast = NULL;
        }
        //jeśli głowa istnieje
        else{
                pracownik *wsk = NULL;
                for(wsk = glowa; wsk->nast != NULL; wsk = wsk->nast){ }
                wsk->nast = dodaj;
                wsk->nast->nast = NULL;
       
        }
       
}

Rzecz w tym, że chcę to wszystko robić jedną funkcją z wykorzystanie polimorfizmu. Jeszcze dla wyjaśnienia dodam, że drugi argument który przyjmuje funkcja dodajp, to obiekt utworzony przez funkcję dodawania nowego pracownika. Analogicznie dla studenta.

W mainie dodaję tylko student *glowa; pracownik *glowa. Ktoś mi powie, czy muszę zmienić wszystkie funkcje włączając w to dodawanie do listy, czy da się jakoś zrobić np. tylko wyświetlanie z wykorzystaniem polimorfizmu?

 


void pokazs(student* glowa){
        
		fun("Wyświetlanie listy studentów"); 
        student* a;
       
        cout << "\t\t** STUDENCI ** \n\n";
        cout << "Nr ID\t\tNazwisko\tOcena\n\n";
       
        for(a = glowa; a != NULL; a = a->nast){
                a->wypisz();
        }
 
        cout << endl;
       
}
 
0

W takim razie to musi być jedna wspólna lista osób, zamiast listy pracowników i listy studentów.

void dodajp(Osoba*& glowa, Osoba* nowa)

W najlepiej to lista powinna być klasą, a dodaj jej metodą.

0

ehh, tak też myślałem. Dobra, przerobię dodawanie i będę pytał dalej

0

Dobra, to załóżmy, że mam coś takiego:


class lista{
protected:
	pracownik *glowa_pracownik;
	student *glowa_student;
	
public:
	lista():
	  glowa_student(NULL), glowa_pracownik(NULL) {}

	  void dodaj(student *dodaj_s){
		  if(glowa_student == NULL){
			  glowa_student = dodaj_s;
			  glowa_student->nast = NULL;
		  }else{
			  student *wsk;

			  for(wsk=glowa_student; wsk->nast!= NULL; wsk = wsk->nast);
			  wsk->nast = dodaj_s;
			  wsk->nast->nast = NULL;
		  }
	  }
		  void dodaj(pracownik *dodaj_p){
			  if(glowa_pracownik == NULL){
				  glowa_pracownik = dodaj_p;
				  glowa_pracownik->nast = NULL;
			  }else{
				  pracownik *wsk;

				  for(wsk = glowa_pracownik; wsk->nast!=NULL; wsk=wsk->nast);
				  wsk->nast = dodaj_p;
				  wsk->nast->nast = NULL;
			  }
		  }

		  void wypisz(){
			  student *a;
			  pracownik *b;

			  cout << "      ** LISTA STUDENTOW **" << endl;
			  for(a=glowa_student; a!=NULL; a=a->nast){
				  a->wypisz();
				  cout << endl << endl;
			  }

			  cout << "     ** LISTA PRACOWNIKOW **" << endl;
			  for(b=glowa_pracownik; b!=NULL; b=b->nast){
				  b->wypisz();
				  cout << endl << endl;
		  }
		  }
		  

 
0

Przejrzyj sobie kod parsera: http://kaczus.republika.pl/izv/parser.lha Był on dodawany do prehistorycznego kompilatora MaxonC, ale bardzo fajnie tam zastosowany polimorfizm. W dawnych czasach rozpoznawałem ten przykład i kila rzeczy opisałem w magazynie Izviestia. Artykuł jest przedpotopowy, ale może pomoż tez coś zrozumieć (albo bardziej zagmatwa) http://kaczus.republika.pl/izv/parser.html

0

Nie, jedna lista, nie dwie listy opakowane w jedną klasę.

class List
{
public:
    void add(Person* newPerson);
    void show();
protected:
    Person* head = nullptr;
};
0
class lista{
protected:
	osoba *glowa;

public:
	lista(){
		glowa = NULL;
	
	}

	void dodaj(osoba *dodaj){
		  if(glowa == NULL){
			  glowa = dodaj;
			  glowa->nast = NULL;
		  }else{
			  osoba *wsk;

			  for(wsk=glowa; wsk->nast!= NULL; wsk = wsk->nast);
			  wsk->nast = dodaj;
			  wsk->nast->nast = NULL;
		  }
	}
		  
		  
};

No dobra, mam taką klasę. Ale mam tam

void dodaj(osoba*dodaj)

a na przykład chcę dodać studenta. A przecież student != osoba.

  1. Po pierwsze, u mnie funkcja dodawania nowego studenta wygląda tak:
 		
student *dodaj_s(student *glowa){
        fun("Dodawanie studenta:  ");
        int a;
        string naz;
        student *wsk = glowa;
 
        cout << "Podaj nr ID studenta: ";
        while((scanf_s("%d", &a))!=1 || a<=9999 || a>=100000 || getchar()!='\n'){
                cout << "Nr ID musi skladac sie z 5 cyfr!\n" ;
                cout << "Wprowadz ponownie:\n" ;
                while(getchar()!='\n');
        }
        while(wsk!=NULL){
                int ID = wsk->getID();
                if(ID == a){
                        cout << "Student z takim ID juz figuruje w bazie\n";
                        while((scanf_s("%d", &a))!=1 || a<=9999 || a>=100000 || getchar()!='\n'){
                                cout << "Nr ID musi skladac sie z 5 cyfr!\n" ;
                                cout << "Wprowadz ponownie:\n" ;
                                while(getchar()!='\n');
               
                                }
                        wsk = glowa;
                }
        wsk = wsk->nast;
        }
        cout << "\nPodaj nazwisko studenta: ";
        cin >> naz;
 
        return new student(a,naz,-1);
}

chyba nie można dodać funkcji wirtualnej innej niż void, więc nie zwrócę w returnie nowego studenta

0
adamtt napisał(a):

A przecież student != osoba.
Oczywiście, że student jest osobą. Na tym polega dziedziczenie!

chyba nie można dodać funkcji wirtualnej innej niż void, więc nie zwrócę w returnie nowego studenta
Funkcja wirtualna może zwracać cokolwiek. Co więcej, wersja w klasie pochodnej może zwracać coś innego niż wersja w klasie bazowej, np.

struct Osoba
{
    virtual Osoba* foo() = 0;
};

struct Student : public Osoba
{
    virtual Student* foo() override;
}
0

Teraz mam problem m.in. z tym, że nie mogę zwrócić

new student(x,y,z) 

ponieważ chyba uznaje mi klasę student jako abstrakcyjną.

 
#include<string>
#include <time.h>
#include<iostream>
#include<fstream>


#define N 20
 
using namespace std;
 
class osoba{
protected:
        float ocena;
        string nazwisko;
public:
	osoba *nast;
                osoba(float ocena1, string nazwisko1):    ////konstruktor dodaj
                ocena(ocena1), nazwisko(nazwisko1) {}
       
                virtual void wypisz()=0;   //metoda wirtualna - wypisz
				virtual void dodaj()=0;
                ///setery
               
                void setOcena (float ocena1){ ocena = ocena1;}
                void setNazwisko (string Nazwisko) {nazwisko = Nazwisko;}
 
                //getery
 
                float getOcena (){ return ocena;}
                string getNazwisko () {return nazwisko ;}
};
 
class student:public osoba{
protected:
        int ID;
       
public:
 
        student *nast;
 
        student(int ID1, string nazwisko1,float ocena1):
        ID(ID1), osoba(ocena1, nazwisko1) {}
 
 
        void wypisz(){
                cout << ID<< "\t\t";
                cout << nazwisko<< "\t\t";
       
                if(ocena!=-1){
                        printf("%.1f\t\t\n\n", ocena);
                }else{
                        cout << "\n\n";
                }
        }
 
        ///setery
 
        void setID (int id) {id = ID;}
 
        //getery
 
        int getID (){return ID;}
 
        ~student(){
        delete nast;
}

		void *nowy(){

		int a;
        string naz;
 
        cout << "Podaj nr ID studenta: ";
        while((scanf_s("%d", &a))!=1 || a<=9999 || a>=100000 || getchar()!='\n'){
                cout << "Nr ID musi skladac sie z 5 cyfr!\n" ;
                cout << "Wprowadz ponownie:\n" ;
                while(getchar()!='\n');
        }
        
                int ID;
                
        cout << "\nPodaj nazwisko studenta: ";
        cin >> naz;
 
        return new student(a,naz,-1);

		}
};
 
 
class pracownik:public osoba{
protected:
        int nr_umowy;
       
public:
        pracownik *nast;
 
        pracownik(int nrumowy, string nazwisko1, float ocena1):osoba(ocena1, nazwisko1)
        {
                nr_umowy = nrumowy;
                nazwisko = nazwisko1;
        }
 
        void wypisz(){
                cout << nr_umowy<< "\t\t";
                cout << nazwisko<< "\t\t";
               
                if(ocena !=-1){
                        printf("%.1f\t\t\n\n", ocena);
                }else {
                        printf("\n\n");
                }
                }
 
        ///setery
 
        void setNR(int NR) {nr_umowy = NR;}
 
        ///getery
 
        int getNR() {return nr_umowy;}
 
~pracownik(){
        delete nast;
}
};
 

ofstream wej("raport.txt");
void fun(string aa){
	time_t czas;
	string bum = aa;
	struct tm * ptr;
	time(&czas);
	ptr = localtime(&czas);
	char * data = asctime(ptr);
	//std::cout << "Data: " << data;
	ofstream plikout("raport.txt", ios::app);
	wej << bum << "         Data:  "<<data << endl;

}





class lista{
	
public:
	osoba *glowa;
	
	lista():
	glowa(NULL) {}

	void dodaj(osoba *dodaj){
		if(glowa == NULL){
			glowa = dodaj;
			glowa->nast = NULL;
		}else{
			osoba *wsk;
			for(wsk = glowa;wsk->nast !=NULL; wsk = wsk->nast);
			wsk->nast = dodaj;
			wsk->nast->nast = NULL;
		}

	}

	void wypisz(){
		osoba *a;
		osoba *b;
			
			for(a =this->glowa;a!=NULL;a=a->nast)
				a->wypisz();
			cout << endl;
			
			for(b =this->glowa;b!=NULL;b=b->nast)
				b->wypisz();
			cout << endl;
			
	}
};


int main(){

	lista *nowa = new lista();

	int wybor; 
	while(wybor == 0){
		cout << "1) student = 1\n2)pracownik = 2\n3)wyjscie = 0\n\n";
		cin >> wybor;
		
		student a();
		osoba *wsk;

		if(wybor == 1){
		
		}
		

	}
	
	return 0;
}

0

Dlaczego student ma student* nast? Student nic nie wie o tym, że jest na jakiejś liście, to nie jego problem.

 void *nowy()

nie void*, tylko student*.

I ta cała metoda nowy(), która zwraca wskaźnik do nowego obiektu też nie wygląda najlepiej, ale to już inny problem.

0

student *nast
zostało jeszcze z czasu, kiedy robiłem 2 listy.

No to jeśli ma być student *(), to jak mam do tego zrobić funkcję wirtualną w klasie Osoba?

I jeszcze: Jak mam się odwołać za pomocą

osoba *wsk
do funkcji z klasy student - getID - która zwraca mi wartość pola ID?

No i kurcze, dlaczego kiedy dodam w klasie osoba <quote> virtual void dodaj()=0; </qoute> to klasa student staje się abstrakcyjną i nie mogę zwrócić w tej funkcji która zasłania virtualną new student... ?

0
adamtt napisał(a):

No to jeśli ma być student *(), to jak mam do tego zrobić funkcję wirtualną w klasie Osoba?
http://4programmers.net/Forum/1145700

I jeszcze: Jak mam się odwołać za pomocą

osoba *wsk
do funkcji z klasy student - getID - która zwraca mi wartość pola ID?
osoba też musi mieć taką funkcję, może być czysto wirtualna. Natomiast jeśli ta metoda nie pasuje tam, bo np. pracownik nie ma getID(), to osoba musi mieć jakąś inną funkcję, powiedzmy getIdentity, która w student będzie wołać getID, a w pracownik będzie wołać getNR.

No i kurcze, dlaczego kiedy dodam w klasie osoba
virtual void dodaj()=0;
Przeczytaj jeszcze mój post podany w linku.
virtual student* dodaj() nie przeciąża virtual void dodaj(). Typy zwracane muszą być skorelowane.

0

... nie wiem czemu, ale za pierwszym razem przeczytałem, a raczej tak zrozumiałem, że funkcja void może zwracać cokolwiek... przepraszam ;)

edit: ok, już jest dobrze ;)

Pytań ciąg dalszy:

  1. Przejdźmy do wywoływania funkcji. Na razie będziemy działać pomijając istnienie klasy pracownik. Co mam dodać w funkcji main?
 
int main(){

	lista *nowa = new lista();
	osoba *glowa=NULL;


	int wybor=1; 
	while(wybor != 0){
		cout << "1) student = 1\n2)pracownik = 2\n3)wyjscie = 0\n\n";
		cin >> wybor;
			if(wybor == 1){

			osoba *wsk = new student(osoba::dodaj(glowa));
		        nowa ->dodaj(wsk);
              }
		
	}

	return 0;
}

tak to nie działa, podkreśla ..=new

student

.... więc proszę o wskazówki ;)

0
new student(osoba::dodaj(glowa));
  1. student nie ma konstruktora przyjmującego osoba*.
  2. dodaj() nie jest metodą statyczną, żeby wywołać w ten sposób
  3. wywołanie osoba::dodaj(glowa) jest totalnie bez sensu, nie wiem co chciałeś osiągnąć
0
osoba *o1 = NULL;
o1->dodaj(glowa);
			
nowa->dodaj(o1);

?
To nie zadziała, a poza tym potrzebne jest jakieś wskazanie, że to właśnie studenta ma dodać, a nie pracownika.

0

A po co dodaj() w osoba? Pomijam już techniczny szczegół, że próbujesz wywołać coś na nullu.

wskazanie, że to właśnie studenta ma dodać, a nie pracownika
Nie, dodajesz osobę, a to czy jest pracownikiem czy studentem to nikogo nie obchodzi w momencie dodania. Na tym polega polimorfizm.

0

Czyli od razu mam dać nowa->dodaj(i tu jak mam wywołać *dodaj - czyli funkcję wirtualną z Osoba?)

0

Żeby się skompilowało i działało:

student s;
nowa->dodaj(s.nowy());

Oczywiście widać, że jest to dosyć głupi kawałek kodu. I już wiesz co miałem na myśli mówiąc:

twonek napisał(a):

I ta cała metoda nowy(), która zwraca wskaźnik do nowego obiektu też nie wygląda najlepiej, ale to już inny problem.

To co jest w nowy, powinno być w konstruktorze, wywalasz nowy i potem w kodzie wołasz

nowa->dodaj(new student);
0

Zrobiłem, mam nadzieję, tak jak napisałeś.

 
#include<string>
#include <time.h>
#include<iostream>
#include<fstream>


#define N 20
 
using namespace std;
 
class osoba{
protected:
        float ocena;
        string nazwisko;
public:
	osoba *nast;
                osoba(float ocena1, string nazwisko1):    ////konstruktor dodaj
                ocena(ocena1), nazwisko(nazwisko1) {}
				
                virtual void wypisz()=0;   //metoda wirtualna - wypisz
				virtual osoba *dodaj(osoba *glowa)=0;
				
                
				///setery

                void setOcena (float ocena1){ ocena = ocena1;}
                void setNazwisko (string Nazwisko) {nazwisko = Nazwisko;}
 
	                //getery
				virtual int getID()=0;
                float getOcena (){ return ocena;}
                string getNazwisko () {return nazwisko ;}
};
 
class student:public osoba{
protected:
        int ID;
       
public:
 
        student *nast;
 
        student(int ID1, string nazwisko1,float ocena1):
        ID(ID1), osoba(ocena1, nazwisko1) {}
 
		student(osoba *glowa){
		
			int ID1;
			string naz;
			float a;
			
			ID=ID1;
			nazwisko = naz;
			ocena =a;

			osoba *wsk = glowa;

			cout << "Podaj nr ID studenta: ";
        while((scanf_s("%d", &a))!=1 || a<=9999 || a>=100000 || getchar()!='\n'){
                cout << "Nr ID musi skladac sie z 5 cyfr!\n" ;
                cout << "Wprowadz ponownie:\n" ;
                while(getchar()!='\n');
        }
        while(wsk!=NULL){
			int ID = wsk->getID();
                if(ID == a){
                        cout << "Student z takim ID juz figuruje w bazie\n";
                        while((scanf_s("%d", &a))!=1 || a<=9999 || a>=100000 || getchar()!='\n'){
                                cout << "Nr ID musi skladac sie z 5 cyfr!\n" ;
                                cout << "Wprowadz ponownie:\n" ;
                                while(getchar()!='\n');
               
                                }
                        wsk = glowa;
                }
        wsk = wsk->nast;
        }
        cout << "\nPodaj nazwisko studenta: ";
        cin >> naz;
		
		}
        
		

        void wypisz(){
                cout << ID<< "\t\t";
                cout << nazwisko<< "\t\t";
       
                if(ocena!=-1){
                        printf("%.1f\t\t\n\n", ocena);
                }else{
                        cout << "\n\n";
                }
        }
 
        ///setery
 
        void setID (int id) {id = ID;}
 
        //getery
 
        int getID (){return ID;}
 
        ~student(){
        delete nast;
}

};
 
 
class pracownik:public osoba{
protected:
        int nr_umowy;
       
public:
        pracownik *nast;
 
        pracownik(int nrumowy, string nazwisko1, float ocena1):osoba(ocena1, nazwisko1)
        {
                nr_umowy = nrumowy;
                nazwisko = nazwisko1;
        }
 
        void wypisz(){
                cout << nr_umowy<< "\t\t";
                cout << nazwisko<< "\t\t";
               
                if(ocena !=-1){
                        printf("%.1f\t\t\n\n", ocena);
                }else {
                        printf("\n\n");
                }
                }
 
        ///setery
 
        void setNR(int NR) {nr_umowy = NR;}
 
        ///getery
 
        int getNR() {return nr_umowy;}
 
~pracownik(){
        delete nast;
}
};
 

ofstream wej("raport.txt");
void fun(string aa){
	time_t czas;
	string bum = aa;
	struct tm * ptr;
	time(&czas);
	ptr = localtime(&czas);
	char * data = asctime(ptr);
	//std::cout << "Data: " << data;
	ofstream plikout("raport.txt", ios::app);
	wej << bum << "         Data:  "<<data << endl;

}





class lista{
	
public:
	osoba *glowa;
	
	lista():
	glowa(NULL) {}

	void dodaj(osoba *dodaj){
		if(glowa == NULL){
			glowa = dodaj;
			glowa->nast = NULL;
		}else{
			osoba *wsk;
			for(wsk = glowa;wsk->nast !=NULL; wsk = wsk->nast);
			wsk->nast = dodaj;
			wsk->nast->nast = NULL;
		}

	}

	void wypisz(){
		osoba *a;
		osoba *b;
			
			for(a =this->glowa;a!=NULL;a=a->nast)
				a->wypisz();
			cout << endl;
			
			for(b =this->glowa;b!=NULL;b=b->nast)
				b->wypisz();
			cout << endl;
			
	}
};


int main(){

	lista *nowa = new lista();
	osoba *glowa=NULL;


	int wybor=1; 
	while(wybor != 0){
		cout << "1) student = 1\n2)pracownik = 2\n3)wyjscie = 0\n\n";
		cin >> wybor;
			
		if(wybor == 1){
			nowa->dodaj(new student(glowa));
		}
		
		
	}

	nowa->wypisz();
	
	
	return 0;
}

Oczywiście nadal jest coś nie tak:

  1. error C2259: 'student' : cannot instantiate abstract class
  2. error C2512: 'osoba' : no appropriate default constructor available
  3. IntelliSense: no default constructor exists for class "osoba"
  4. IntelliSense: object of abstract class type "student" is not allowed
0
  1. Korzystaj z formatera
  2. Wywal dodaj() z osoba
  3. Jak podajesz błąd to podaj również linijkę kodu, której ten błąd dotyczy
  4. Po co studentowi głowa listy?
0

Dzięki za formater, szukałem czegoś takiego ;)
Głowa mi jest potrzebna, żeby przejść przez całą listę i sprawdzić, czy istnieje już student z takim ID.

0

To nie zadanie dla studenta, tylko listy.

0
#include <string>
#include <time.h>
#include <iostream>
#include <fstream>

#define N 20

using namespace std;

class osoba {
protected:
    float ocena;
    string nazwisko;

public:
    osoba* nast;

    osoba(float ocena1, string nazwisko1)
    { ////konstruktor dodaj
        ocena = ocena1;
        nazwisko = nazwisko1;
    }

    osoba()
    { ////konstruktor dodaj
        ocena = -1;
        nazwisko = "none";
    }

    virtual void wypisz() = 0; //metoda wirtualna - wypisz

    ///setery

    void setOcena(float ocena1) { ocena = ocena1; }
    void setNazwisko(string Nazwisko) { nazwisko = Nazwisko; }
    
	virtual void setID(int id) = 0;
	virtual void setNR(int nr) = 0;

    //getery

    virtual int getID() = 0;
	virtual int getNR() = 0;
    
	float getOcena() { return ocena; }
    string getNazwisko() { return nazwisko; }
};

class student : public osoba {
protected:
    int ID;

public:
    student* nast;

    student(int ID1, string nazwisko1, float ocena1)
        : ID(ID1)
        , osoba(ocena1, nazwisko1)
    {
    }

    student(osoba* glowa)
    {

        string naz = "null";
        osoba* wsk = glowa;
        int a = NULL;

        //ID = a;
        //nazwisko = naz;

        cout << "Podaj nr ID studenta: ";
        while ((scanf_s("%d", &a)) != 1 || a <= 9999 || a >= 100000 || getchar() != '\n') {
            cout << "Nr ID musi skladac sie z 5 cyfr!\n";
            cout << "Wprowadz ponownie:\n";
            while (getchar() != '\n')
                ;
        }
        while (wsk != NULL) {
            int ID = wsk->getID();
            if (ID == a) {
                cout << "Student z takim ID juz figuruje w bazie\n";
                while ((scanf_s("%d", &a)) != 1 || a <= 9999 || a >= 100000 || getchar() != '\n') {
                    cout << "Nr ID musi skladac sie z 5 cyfr!\n";
                    cout << "Wprowadz ponownie:\n";
                    while (getchar() != '\n')
                        ;
                }
                wsk = glowa;
            }
            wsk = wsk->nast;
        }
        cout << "\nPodaj nazwisko studenta: ";
        cin >> naz;

        ID = a;
        nazwisko = naz;
    }

    void wypisz()
    {
        cout << ID << "\t\t";
        cout << nazwisko << "\t\t";

        if (ocena != -1) {
            printf("%.1f\t\t\n\n", ocena);
        }
        else {
            cout << "\n\n";
        }
    }

    ///setery

	void setNR(int nr) {this->setNR(nr); }
    void setID(int id) { id = ID; }

    //getery
	int getNR() {return this->getNR();}
    int getID() { return ID; }

    ~student()
    {
        delete nast;
    }
};

class pracownik : public osoba {
protected:
    int nr_umowy;

public:
    pracownik* nast;

    pracownik(int NR1, string nazwisko1, float ocena1)
        : nr_umowy(NR1)
        , osoba(ocena1, nazwisko1)
    {
    }

    
	pracownik(osoba* glowa)
    {

        string naz = "null";
        osoba* wsk = glowa;
        int a = NULL;

        //ID = a;
        //nazwisko = naz;

        cout << "Podaj nr umowy pracownika: ";
        while ((scanf_s("%d", &a)) != 1 || a <= 999999 || a >= 10000000 || getchar() != '\n') {
            cout << "Nr umowy musi skladac sie z 7 cyfr!\n";
            cout << "Wprowadz ponownie:\n";
            while (getchar() != '\n')
                ;
        }
        while (wsk != NULL) {
            int ID = wsk->getID();
            if (ID == a) {
                cout << "Pracownik z takim nr juz figuruje w bazie\n";
                while ((scanf_s("%d", &a)) != 1 || a <= 999999 || a >= 10000000 || getchar() != '\n') {
                    cout << "Nr umowy musi skladac sie z 7 cyfr!\n";
                    cout << "Wprowadz ponownie:\n";
                    while (getchar() != '\n')
                        ;
                }
                wsk = glowa;
            }
            wsk = wsk->nast;
        }
        cout << "\nPodaj nazwisko pracownika: ";
        cin >> naz;

        nr_umowy = a;
        nazwisko = naz;
    }

	
	void wypisz()
    {
        cout << nr_umowy << "\t\t";
        cout << nazwisko << "\t\t";

        if (ocena != -1) {
            printf("%.1f\t\t\n\n", ocena);
        }
        else {
            printf("\n\n");
        }
    }

    ///setery
	void setID(int id) {this->setID(id);}
    void setNR(int NR) { nr_umowy = NR; }

    ///getery
	int getID() {return this->getID(); }
    int getNR() { return nr_umowy; }

    ~pracownik()
    {
        delete nast;
    }
};

ofstream wej("raport.txt");
void fun(string aa)
{
    time_t czas;
    string bum = aa;
    struct tm* ptr;
    time(&czas);
    ptr = localtime(&czas);
    char* data = asctime(ptr);
    //std::cout << "Data: " << data;
    ofstream plikout("raport.txt", ios::app);
    wej << bum << "         Data:  " << data << endl;
}

class lista {

public:
    osoba* glowa;

    lista()
        : glowa(NULL)
    {
    }

    void dodaj(osoba* dodaj)
    {
        if (glowa == NULL) {
            glowa = dodaj;
            glowa->nast = NULL;
        }
        else {
            osoba* wsk;
            for (wsk = glowa; wsk->nast != NULL; wsk = wsk->nast)
                ;
            wsk->nast = dodaj;
            wsk->nast->nast = NULL;
        }
    }

    void wypisz_s()
    {
        osoba* a;

        for (a = this->glowa; a != NULL; a = a->nast){
            if (a->getID() < 100000) {
                a->wypisz();
                cout << endl;
            }
		}
	}

	void wypisz_p()
    {
        osoba* a;

        for (a = this->glowa; a != NULL; a = a->nast){
            if (a->getID() >999999) {
                a->wypisz();
                cout << endl;
            }
		}
	}



};


int main()
{

    lista* nowa = new lista();
    osoba* glowa = NULL;

    int wybor = 1;
    while (wybor != 0) {
        cout << "1) student = 1\n2)pracownik = 2\n3)wyjscie = 0\n\n";
        cin >> wybor;

        if (wybor == 1) {

            nowa->dodaj(new student(glowa));
        }

		if(wybor == 2){
			nowa->dodaj(new pracownik(glowa));
		}
    }

    nowa->wypisz_s();
	nowa->wypisz_p();

    return 0;
}

Dzięki, pomogło ;)
Odświeżyłem swój kod. Problem z wyświetlaniem, ale trochę pokombinuję sam

0

Pracownik i student to klasy abstrakcyjnie, nie można utworzyć obiektów tych typów. Możesz użyć konstrukcji

 Student *student = new KlasaImplementujacaKlaseStudent

Tak samo z pracownikiem.</del>

Student nie implementuje wszystkich funkcji wirtualnych z klasy osoba :) getNr() i setNr()
A z tego co widzę pracownik nie implementuje getId() i setId().
Żeby można było utworzyć obiekty tych klas wszystkie funkcje wirtualne muszą zostać zaimplementowane, te dziedziczone też.

btw. kompilator nie wywala błędów typu "cośtamcośtam vtable[] not implemented"?

0

Ok. To teraz wystawianie oceny ;) Czy da się dodać funkcję wirtualną w klasie 'osoba', tak aby wywoływała zgodnie z oczekiwaniami albo metodę studenta, albo pracownika? Czy mam to wywoływać jako konstruktor, tak jak próbuję, lecz mi nie wychodzi?

 
#include <string>
#include <time.h>
#include <iostream>
#include <fstream>

#define N 20

using namespace std;

/////////////deklaracje

void fun(string aa);
void menu();

class osoba {
protected:
    float ocena;
    string nazwisko;

public:
    osoba* nast;

    osoba(float ocena1, string nazwisko1)
    { ////konstruktor dodaj
        ocena = ocena1;
        nazwisko = nazwisko1;
    }

    osoba()
    { ////konstruktor dodaj
        ocena = -1;
        nazwisko = "none";
    }

    virtual void wypisz() = 0; //metoda wirtualna - wypisz
//    virtual osoba* ocen(osoba* glowa, int id) = 0;
    ///setery

    void setOcena(float ocena1) { ocena = ocena1; }
    void setNazwisko(string Nazwisko) { nazwisko = Nazwisko; }

    virtual void setID(int id) = 0;
    virtual void setNR(int nr) = 0;

    //getery

    virtual int getID() = 0;
    virtual int getNR() = 0;

    float getOcena() { return ocena; }
    string getNazwisko() { return nazwisko; }
};

class student : public osoba {
protected:
    int ID;

public:
    student* nast;

    student(int ID1, string nazwisko1, float ocena1)
        : ID(ID1)
        , osoba(ocena1, nazwisko1)
    {
    }

    student(osoba* glowa)
    {

        string naz = "null";
        osoba* wsk = glowa;
        int a = NULL;

        //ID = a;
        //nazwisko = naz;

        cout << "Podaj nr ID studenta: ";
        while ((scanf_s("%d", &a)) != 1 || a <= 9999 || a >= 100000 || getchar() != '\n') {
            cout << "Nr ID musi skladac sie z 5 cyfr!\n";
            cout << "Wprowadz ponownie:\n";
            while (getchar() != '\n')
                ;
        }
        while (wsk != NULL) {
            int ID = wsk->getID();
            if (ID == a) {
                cout << "Student z takim ID juz figuruje w bazie\n";
                while ((scanf_s("%d", &a)) != 1 || a <= 9999 || a >= 100000 || getchar() != '\n') {
                    cout << "Nr ID musi skladac sie z 5 cyfr!\n";
                    cout << "Wprowadz ponownie:\n";
                    while (getchar() != '\n')
                        ;
                }
                wsk = glowa;
            }
            wsk = wsk->nast;
        }
        cout << "\nPodaj nazwisko studenta: ";
        cin >> naz;

        ID = a;
        nazwisko = naz;
    }

    student(osoba* glowa, int id)
    {
        fun("Edycja oceny studenta:  ");
        osoba* wsk;
        wsk = glowa;

        while (wsk != NULL) {
			if (wsk->getID() == id) {
                float ocena;

                while ((scanf_s("%f", &ocena)) != 1 || ocena != 2 && ocena != 3 && ocena != 3.5 && ocena != 4 && ocena != 4.5 && ocena != 5 || getchar() != '\n') {
                    cout << "Ocena to cyfra z przedziału [2,5]! Uwzgledniane sa oceny polowiczne.\n";
                    cout << "Wprowadz ponownie:\n";
                    while (getchar() != '\n')
                        ;
                }

				wsk->setOcena(ocena);
                
            }
            wsk = wsk->nast;
        }
    }

    void wypisz()
    {
        cout << ID << "\t\t";
        cout << nazwisko << "\t\t";

        if (ocena != -1) {
            printf("%.1f\t\t\n\n", ocena);
        }
        else {
            cout << "\n\n";
        }
    }

    ///setery

    void setNR(int id) { id = ID; }
    void setID(int id) { id = ID; }

    //getery
    int getNR() { return ID; }
    int getID() { return ID; }

    ~student()
    {
        delete nast;
    }
};

class pracownik : public osoba {
protected:
    int nr_umowy;

public:
    pracownik* nast;

    pracownik(int NR1, string nazwisko1, float ocena1)
        : nr_umowy(NR1)
        , osoba(ocena1, nazwisko1)
    {
    }

    pracownik(osoba* glowa)
    {

        string naz = "null";
        osoba* wsk = glowa;
        int a = NULL;

        //ID = a;
        //nazwisko = naz;

        cout << "Podaj nr umowy pracownika: ";
        while ((scanf_s("%d", &a)) != 1 || a <= 999999 || a >= 10000000 || getchar() != '\n') {
            cout << "Nr umowy musi skladac sie z 7 cyfr!\n";
            cout << "Wprowadz ponownie:\n";
            while (getchar() != '\n')
                ;
        }
        while (wsk != NULL) {
            int ID = wsk->getID();
            if (ID == a) {
                cout << "Pracownik z takim nr juz figuruje w bazie\n";
                while ((scanf_s("%d", &a)) != 1 || a <= 999999 || a >= 10000000 || getchar() != '\n') {
                    cout << "Nr umowy musi skladac sie z 7 cyfr!\n";
                    cout << "Wprowadz ponownie:\n";
                    while (getchar() != '\n')
                        ;
                }
                wsk = glowa;
            }
            wsk = wsk->nast;
        }
        cout << "\nPodaj nazwisko pracownika: ";
        cin >> naz;

        nr_umowy = a;
        nazwisko = naz;
    }

    osoba* ocen(osoba* glowa, int nr)
    {
        fun("Edycja oceny pracownika:  ");
        osoba* wsk;
        wsk = glowa;

        while (wsk != NULL) {
            if (wsk->getNR() == nr) {
                float ocena;

                while ((scanf_s("%f", &ocena)) != 1 || ocena < 0 || ocena > 5 || getchar() != '\n') {
                    cout << "Ocena to liczba z przedzialu [0,5]!\n";
                    cout << "Wprowadz ponownie:\n";
                    while (getchar() != '\n')
                        ;
                }
                wsk->setOcena(ocena);
                return wsk;
            }
            wsk = wsk->nast;
        }
    }

    void wypisz()
    {
        cout << nr_umowy << "\t\t";
        cout << nazwisko << "\t\t";

        if (ocena != -1) {
            printf("%.1f\t\t\n\n", ocena);
        }
        else {
            printf("\n\n");
        }
    }

    ///setery
    void setID(int id) { nr_umowy = id; }
    void setNR(int NR) { nr_umowy = NR; }

    ///getery
    int getID() { return nr_umowy; }
    int getNR() { return nr_umowy; }

    ~pracownik()
    {
        delete nast;
    }
};

class lista {

public:
    osoba* glowa;

    lista()
        : glowa(NULL)
    {
    }

    void dodaj(osoba* dodaj)
    {
        if (glowa == NULL) {
            glowa = dodaj;
            glowa->nast = NULL;
        }
        else {
            osoba* wsk;
            for (wsk = glowa; wsk->nast != NULL; wsk = wsk->nast)
                ;
            wsk->nast = dodaj;
            wsk->nast->nast = NULL;
        }
    }

    void wypisz_s()
    {
        fun("Wyświetlanie listy studentów");
        osoba* a;

        cout << "\t\t** STUDENCI ** \n\n";
        cout << "Nr ID\t\tNazwisko\tOcena\n\n";

        for (a = glowa; a != NULL; a = a->nast) {
            if (a->getID() < 100000)
                a->wypisz();
        }
    }

    void wypisz_p()
    {
        fun("Wyświetlanie listy pracowników:  ");
        osoba* b;

        cout << "\t\t**  PRACOWNICY ** \n\n";
        cout << "Nr \t\tNazwisko\tOcena\numowy\n\n";
        for (b = glowa; b != NULL; b = b->nast) {
            if (b->getNR() > 999999)
                b->wypisz();
        }

        cout << endl;
    }
};

int main()
{

    lista* nowa = new lista();
    osoba* glowa = NULL;
	osoba*wsk = glowa;

    int wybor = 1;
    while (wybor != 0) {
        menu();
        cin >> wybor;
        system("cls");
        if (wybor == 1) {

            nowa->dodaj(new student(glowa));
            system("cls");
        }

        if (wybor == 2) {
            nowa->dodaj(new pracownik(glowa));
            system("cls");
        }

		if (wybor == 3) {
        //osoba* wsk;
        //wsk = glowa;
        int nr1;

        cout << "Podaj ID studenta, ktorego ocene chcesz zmienic:\n";
        cin >> nr1;
        cout << "Wpisz ocene:\n";
        student(glowa, nr1);
    }
		/*
	if (wybor == 4) {
        osoba* wsk;
        wsk = glowa;
        int nr1;

        cout << "Podaj nr umowy pracownika, ktorego ocene chcesz zmienic:\n";
        cin >> nr1;
        cout << "Wpisz ocene:\n";
        wsk->ocen(glowa, nr1);
    }
	*/

        if (wybor == 10) {
            nowa->wypisz_s();
            nowa->wypisz_p();
            system("pause");
            system("cls");
        }
    }
    
    

    return 0;
    delete nowa;
}

void menu()
{
    fun("Wyswietlanie MENU:  ");
    cout << "\n\n\t\t**MENU**\n\n";
    cout << "1) Dodaj nowego studenta\n";
    cout << "2) Dodaj nowego pracownika\n";
    cout << "3) Wystaw ocene studentowi\n";
    cout << "4) Ocen pracownika\n";
    cout << "5) Usun studenta z listy\n";
    cout << "6) Usun pracownika z listy\n";
    cout << "7) Drukuj\n";
    cout << "8) Sprawdz, ilu studentow otrzymalo dana ocene\n";
    cout << "9) Sortuj wzgledem oceny\n";
    cout << "\n10) Wyswietl aktualna liste\n";
    cout << "0) WYJSCIE\n\n";
    cout << "Co chcesz zrobić? :\n " << endl;
}

ofstream wej("raport.txt");
void fun(string aa)
{
    time_t czas;
    string bum = aa;
    struct tm* ptr;
    time(&czas);
    ptr = localtime(&czas);
    char* data = asctime(ptr);
    //std::cout << "Data: " << data;
    ofstream plikout("raport.txt", ios::app);
    wej << bum << "         Data:  " << data << endl;
}


0

To jest bezsensu, bo nie uwzględniasz żadnych podpowiedzi z postów innych użytkowników.
Wróc do nauki czym są klasy , jak ich używać, co to jest lista itd., no niestety nic nie ogarniasz.

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