#include <iostream>


class ApstraktniStudent{
    std::string ime, prezime;
    int indeks, broj_polozenih;
    double prosjek;
    public:
     ApstraktniStudent(std::string ime, std::string prezime, int indeks) : 
            ime(ime), prezime(prezime), indeks(indeks), broj_polozenih(0), prosjek(5){}
    virtual ~ApstraktniStudent() = default;
    std::string DajIme() const {return ime;}
    std::string DajPrezime() const {return prezime;}
    int DajBrojIndeksa() const {return indeks;}
    int DajBrojPolozenih() const {return broj_polozenih;}
    double DajProsjek() const {return prosjek;}
    void RegistrirajIspit(int ocjena){
        if(ocjena < 5 || ocjena > 10) throw std::domain_error("Neispravna ocjena");
        if(ocjena == 5) return;
        prosjek = (prosjek * broj_polozenih + ocjena) / (broj_polozenih + 1);
        broj_polozenih++;
        
    }
    void PonistiOcjene() {
        broj_polozenih = 0;
        prosjek = 5.;
        
    }
    virtual void IspisiPodatke() const = 0;
    virtual ApstraktniStudent *DajKopiju() const = 0;

};

class StudentBachelor : public ApstraktniStudent{
    public 
    void IspisiPodatke() const override {
        std::cout<<"Student Bachelor studija "<<DajIme()<<" "<<DajPrezime()<<", sa brojem indeksa "<<
            indeks<<DajBrojIndeksa()<<" ima prosjek"<<DajProsjek();
    }

    ApstraktniStudent *DajKopiju() const override{return new StudentBachelor(*this);}

};

class StudentMaster : public ApstraktniStudent{
    int godina_diplomiranja; 
    public:
    StudentMaster(std::string ime, std::string prezime, int indeks, int godina_diplomiranja) 
            : ApstraktniStudent(ime, prezime, indeks), godina_diplomiranja(godina_diplomiranja){}
    
            
    void IspisiPodatke() const override {
        std::cout<<"Student Bachelor studija "<<DajIme()<<" "<<DajPrezime()<<", sa brojem indeksa "<<
            indeks<<DajBrojIndeksa()<<"zavrsio bachelor studij godine "<<godina<<" ima prosjek"<<DajProsjek();
    }

    ApstraktniStudent *DajKopiju() const override{return new StudentMaster(*this);}

};

class Fakultet : public ApstraktniStudent{
    std::vector<ApstraktniStudent*> studenti;
    int NadjiStudenta(int indeks, bool treba_postojati) const;
    public: 
    ~Fakultet() { for(ApstraktniStudent *s : studenti) delete s; }
    Fakultet(const Fakultet &f);
    Fakultet(Fakultet &&f) = default;
    Fakultet &operator =(Fakultet f){std::swap(studenti, f.studenti); return *this;}
    void UpisiStudenta(std::string ime, std::string prezime, int indeks);
    void UpisiStudenta(std::string ime, std::string prezime, int indeks, int godina_diplomiranja);
    void ObrisiStudenta(int indeks);
    ApstraktniStudent &operator [](int indeks);
    const ApstraktniStudent &operator [](int indeks)const;
    void IspisiSveStudente() const;
    
    
};

Fakultet::Fakultet(const Fakultet &f) : studenti(f.studenti.size()){
    try{
        for(int i = 0; i < studenti.size(); i++) studenti[i] = f.studenti[i]->DajKopiju();
    } catch(...){
        for(ApstraktniStudent *s : studenti) delete s;
        throw;
    }
}



int Fakultet::NadjiStudenta(indeks, bool treba_postojati) const{
    int i;
    (for i = 0; i < studenti.size(); i++)
        if(studenti[i]->DajBrojIndeksa()==indeks) break;
        if(treba_postojati && i==studenti.size())
            throw std::logic_error("Student sa zadanim brojem indeksa ne postoji");
        if(!treba_postojati && i != studenti.size())
            throw std::logic_error("Student sa zadanim brojem indeksa vec postoji");
    return i;
    
}

void Fakultet::UpisiStudenta(std::string ime, std::string prezime, int indeks){
    NadjiStudenta(indeks, false);
    studenti.pushback(new StudentBachelor (ime, prezime, indeks));

}
void Fakultet::UpisiStudenta(std::string ime, std::string prezime, int indeks, int godina_diplomiranja){
    NadjiStudenta(indeks, false);
    studenti.pushback(new StudentMaster (ime, prezime, indeks, godina_diplomiranja));

}
void Fakultet::ObrisiStudenta(int indeks){
    int gdje_je = NadjiStudenta(indeks, true);
    delete studenti[gdje_je];
    studenti.erase(studenti.begin() + gdje_je);
}

ApstraktniStudent &Fakultet::operator [](int indeks){
        return *studenti[NadjiStudenta(indeks, true)];
    }

const ApstraktniStudent &Fakultet::operator [](int indeks) const{
        return *studenti[NadjiStudenta(indeks, true)];
    }
void Fakultet::IspisiSveStudente() const{
    auto studenti_kopija = studenti;
    std::sort(studenti_kopija.begin(), studenti_kopija.end, [](ApstraktniStudent *s1, ApstraktniStudent *s2) { 
    if(s1->DajProsjek() != s2->DajProsjek()) return s1->DajProsjek() > s2->DajProsjek(); 
    return s1->DajBrojIndeksa() < s2->DajBrojIndeksa(); 
});
    for(ApstraktniStudent *s : studenti_kopija) s->IspisiPodatke();
        
}





int main() {
    std::cout << "Hello world!" << std::endl;
    return 0;
}

Embed on website

To embed this project on your website, copy the following code and paste it into your website's HTML: