problem przy próbach poradzenia sobie z dziedziczeniem klas

0

Uczę się c++. Próbuję napisać coś z dziedziczeniem klas ale dostaję błąd którego znaczenia nie rozumiem - "main.cpp |11 & 12| error: 'Student' is an ambiguous base of 'Wynik'|". Myślałem żeby pokombinować z "virtual" ale to nie dało rezultatu. Proszę o pomoc.

main.cpp :

#include <iostream>
#include "zajecia.h"

using namespace std;

int main()
{
    Wynik pierwszy;
    Wynik * drugi = new Wynik;

    pierwszy.Student::setterem(46627); // Tutaj wyskakuje błąd
    drugi->Student::setterem(46628); // Tutaj wyskakuje błąd
    pierwszy.Kolokwium::setterem(3.5, 4, 4);
    drugi->Kolokwium::setterem(4.5,5,5);
    pierwszy.Egzamin::setterem(3.5);
    drugi->Egzamin::setterem(4);

    pierwszy.Wynik::obliczWynik();
    drugi->Wynik::obliczWynik();

    pierwszy.wyswietlWynik();
    drugi->wyswietlWynik();

    delete drugi;
    return 0;
}

zajecia.h :

#include <iostream>

class Student{
protected:
    int nrindeksu;
public:
    ~Student(){}
    void setterem(int indeks);
    void wyswietlNrIndeksu();
};

class Kolokwium : public Student{  // Kiedy usunę dziedziczenie  w tym miejscu to błąd znika ale nie chcę tego
protected:                        // robić - chcę wiedzieć dlaczego tak się dzieje lub jak rozwiązać ten problem w inny sposób
    double wynikKol1;
    double wynikKol2;
    double wynikKol3;
public:
    ~Kolokwium(){}
    void setterem(double K1, double K2, double K3);
    void WyswietlWynikiKolokwium();
};

class Egzamin : public Student{
protected:
    double wynik_egzaminu;
public:
    ~Egzamin(){}
    void setterem(double egzamin);
    void wyswietlWynikEgzaminu();
};

class Wynik : public Kolokwium, public Egzamin{
    double wynikStudenta;
public:
    ~Wynik(){}
    void obliczWynik();
    void wyswietlWynik();
};

zajecia.cpp :

#include "zajecia.h"

using namespace std;

void Student::setterem(int indeks){
    nrindeksu = indeks;
}
void Student::wyswietlNrIndeksu(){
    std::cout << "nr indeksu: " << nrindeksu << std::endl;
}

void Kolokwium::setterem(double K1, double K2, double K3){
    wynikKol1 = K1;
    wynikKol2 = K2;
    wynikKol3 = K3;
}

void Egzamin::setterem(double egzamin) {
    wynik_egzaminu = egzamin;
}

void Egzamin::wyswietlWynikEgzaminu(){
    std::cout << "Wynik z egzaminu: " << wynik_egzaminu << "pkt" << std::endl;
}

void Wynik::obliczWynik(){
    wynikStudenta = (wynikKol1 + wynikKol2 + wynikKol3) / (3 + 3 * wynik_egzaminu);
}

void Wynik::wyswietlWynik(){
    cout << "Wynik koncowy: " << wynikStudenta << endl;
}

2

Piszesz według jakiejś specyfikacji, czy tak sobie? Bo to co robisz nie ma sensu, egzamin nie jest studentem, kolokwium też nim nie jest.

Jeśli chodzi o samą implementację, dziedziczysz po dwóch różnych klasach, z których każda dziedziczy po (swoim, osobnym) studencie. Możesz dziedziczyć wirtualnie, ale to w tym przypadku bezsens.

2

Ogólnie robisz bardzo dziwne rzeczy z tym dziedziczeniem. Dlaczego uważasz, że Egzamin i Kolokwium powinny dziedziczyć po Studencie? I dlaczego wynik powinien dziedziczyć po Egzaminie i Kolokwium?

0

Piszę to jako zadanie domowe. Właściwie każda linijka kodu jest podyktowana jego treścią.

kq napisał(a):

Możesz dziedziczyć wirtualnie, ale to w tym przypadku bezsens.

class Kolokwium : virtual Student{

Jeżeli chodzi o coś takiego, to to nie działa. Jeżeli nie, to proszę o wskazówkę :)
Ogólnie treść zadania wygląda tak:
"Przekształć program [napisany wg wcześniejszego zadania] tak, aby efekt działania był ten sam,
natomiast hierarchia dziedziczenia była następująca:
Student------->(Kolokwium, Egzamin)------->Wynik"

Dlatego wydaje mi się że może być bezsensownie, byle działało.

0

Ale ten program z poprzedniego zadania przez kogo był napisany? Przez prowadzącego?

3

https://wandbox.org/permlink/vJ59Ll6TuNCaHW84

struct Base
{
	int foo;
};

struct Der1 : virtual Base {};
struct Der2 : virtual Base {};

struct Final : Der1, Der2
{
	Final() : Base{42} {}
};

int main()
{
	Final f;
	DBG(f.foo);
	static_cast<Der1&>(f).foo = 1337;
	DBG(f.foo);
	static_cast<Der2&>(f).foo = 31337;
	DBG(f.foo);
}

Bardzo współczuję prowadzącego. Możesz mu przekazać, że aktywnie robi krzywdę takim sposobem nauczania.

0

Podaj dokładną treść zadania. Bo nie chce mi się wierzyć, że ktoś kazał Wam coś takiego napisać.

0
_dominik napisał(a):

a mógłbyś napisać jak dokładnie brzmiały treści tych dwóch zadań?

zad.1

  1. StwórzsklasęsStudent
    zspolemsnrIndeksusoraz
    getterems(do pobrania numeru indeksu) i metodą wyswietlNrIndeksu()swyświetlającą numer indeksu.
    Pole nrIndeksu nie może być publiczne.

  2. Stwórz klasęsKolokwium dziedziczącąspo klasie Student
    z polami wynikKol1,swynikKol2,swynikKol3 oraz
    (3-parametrowym) getterem (do pobrania wyników każdego kolokwium (w punktach)) i
    metodą wyświetlWynikiKolokwium()swyświelającą wyniki kolokwiów.
    Pola mają byćstypu zmiennoprzecinkowego i nie mogą być publiczne.

  3. Stwórz klasę Egzamin
    z polem wynikEgzaminu oraz
    getterems(do pobrania wyniku egzaminu (w punktach)) i metodą wyświetlWynikEgzaminu()
    wyświetlającąswynik egzaminu.
    Pole wynik_egzaminu ma byćstypu zmiennoprzecinkowego i mie może byćspubliczne.

  4. Stwórz klasęsWyniksdziedziczącą po klasach Kolokwium orazsEgzamin
    zawierającą poleswynikStudenta oraz
    metody obliczWynik()soraz wyswietlWynik() odpowiednio obliczającymi oraz wyświetlającymi
    wynik studenta.
    Pole wynikStudentasma być prywatne.
    Wynik studenta ma być obliczony według wzoru:
    (wynikKol1s+ wynikKol2 +swynikKol3) / 3 +s3 *swynikEgzaminu.

  5. Utwórzsdwóchsstudentów (jednego w sposóbsstatyczny, drugiego w sposóbsdynamiczny) i
    pobierz dla każdego z nich numer indeksu, wyniki kolokwiów oraz wynik egzaminu,
    a następniesoblicz wynik końcowy i go wyświetl.

zad.2
Przekształćsprogram [napisany wg wcześniejszego zadania] tak,saby efektsdziałania był ten sam,
natomiast hierarchiasdziedziczeniasbyłasnastępująca:
Students------>(Kolokwium,sEgzamin)s------>Wynik

0

@Bartłomiej Golenko: teraz wierzysz :D ?

0

No nic, w takim razie musisz zrobić tak jak kq napisał. W Twoim przypadku obie klasy: Egzamin i Kolokwium muszą dziedziczyć wirtualnie po Studencie

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