Wielokrotne dziedziczenie i klasa abstrakcyjna

0

Witam,
Mam problem odnośnie wielokrotnego dziedziczenia, Posiadam hierarchię klas zbudowaną w następujący sposób:

Klasa abstrakcyjna

A

z parametrami: string nazwa i int wartosc

 Która jest klasą bazową dla klas :

```cpp
B, C, D, E, F

w każdej z tych klas zawarty jest dodatkowy parametr int o unikalnej nazwie.

Postanowiłem stworzyć jeszcze jedną podklasę a mianowicie Plik w której będą zawarte elementy z klas bazowych, wszystkich włącznie z A. Wygląda to tak:

calss Plik : public A, public B, public C, public D, public E, public F{/*instrukcje działania na plikach*/}

Błąd pojawia się w trakcie kompilacji gdy chcę się odwołać się po parametru nazwa i wartość, kompilator podpowiedział mi abym użył A::nazwa, A::wartosc lecz to i tak nie spowodowało że mój program się kompiluje, błąd który się pojawia to:Przedmiot' is an ambiguous base of Plik' oraz reference to `nazwa' is ambiguous.
Co powinienem zmienić?

1

Tak się dzieje ponieważ twoja klasa posiada 6 kopii klasy A.
Jedna dziedziczona bezpośrednio a pozostałe dziedziczone pośrednio przez B,C,D,E,F.
Jeżeli chcesz aby była jedna kopia klasy A to klasa B:

class B:virtual public A { ... };

klasy C,D,E,F tak samo.
Klasa Plik:

class Plik:public B,public C,public D,public E,public F { ... };

lub:

class Plik:virtual publicA,public B,public C,public D,public E,public F { ... };

W obu przypadkach na liście inicjalizującej konstruktorów klasy Plik musisz wywołać konstruktor klasy A (no chyba że ma domyślny).

0

Dzięki, program się kompiluje, lecz przekazywane zmienne mają losowe wartości :

Nazwa: Wartosc: -842150451

To otrzymałem po zapisie do pliku. Gdzie może teraz być błąd ?

0
#include<iostream>
#include<fstream>
#include<string>
#include<vector>

#include"Telewizor.h"
#include"Komputer.h"
#include"Obraz.h"
#include"Pendrive.h"
#include"Telefonkom.h"
#include"Przedmiot.h"

using namespace std;

class Plik : public Telewizor, public Komputer, public Obraz, public Pendrive, public Telefonkom/*,virtual public Przedmiot*/ {
      public:
             void zapis(string typ)
             {
                 fstream plik;
                 plik.open("baza.txt", ios::app|ios::out);
                 if(plik.good()==true)
                 {
                 if(typ=="telewizor"){
                 plik<<"Nazwa: "<<Przedmiot::nazwa<<" Wartosc: "<<Przedmiot::wartosc<<" Przekatna: "<<przekatna;
                 plik.close();
                 }
                 if(typ=="komputer"){
                 plik<<"Nazwa: "<<Przedmiot::nazwa<<" Wartosc: "<<Przedmiot::wartosc<<" Ram: "<<ram;
                 plik.close();
                 }
                 if(typ=="obraz"){
                 plik<<"Nazwa: "<<Przedmiot::nazwa<<" Wartosc: "<<Przedmiot::wartosc<<" Rok powstania: "<<rokprod;
                 plik.close();
                 }
                 if(typ=="pendrive"){
                 plik<<"Nazwa: "<<Przedmiot::nazwa<<" Wartosc: "<<Przedmiot::wartosc<<" Pojemnosc: "<<pojemnosc;
                 plik.close();
                 }
                 if(typ=="telfonkom"){
                 plik<<"Nazwa: "<<Przedmiot::nazwa<<" Wartosc: "<<Przedmiot::wartosc<<" Czas czuwania: "<<czasczuwania;
                 plik.close();
                 }
                 }
                 else
                 cout<<"Error(nie udalo sie odnalesc pliku baza.txt)\n";
             }
             
      };
0

Owszem mogę ci pomoc pozbyć się tego konkretnego problemu, z tym że wg mnie to co napisałeś to jakiś absurd.
Napisz może co próbujesz osiągnąć, czy chodzi może o polimorfizm?
To co zrobiłeś reprezentuje pewien obiekt który jest jednocześnie:
Telewizor,
Komputer,
Obraz,
Pendrive,
Telefonkom
Owszem niektóre współczesne komórki potrafią pełnić wszystkie te funkcję naraz (może oprócz obrazu, ale zawsze można założyć etui z rysunkiem), ale raczej to nadal kwalifikuje się jako wyłącznie telefon komórkowy.

0

Chciałem aby nie trzeba było przekazywać parametrów do klasy plik za pomocą jakiejś metody, tylko aby pobiera je automatycznie z nadklas. Wtedy w mainie wystarczyło by wywołać metodę zapisz(); z parametrem "telewizor" a nie przekazywać jej jeszcze nazwa, wartosc, i przekatna.

1

W takim razie:

  • Plik nie powinien być klasą pochodzącą od czegokolwiek.
  • klasa Przedmiot powinna zawierać wirtualną i czystą metodę void zapisz(Plik &P);
  • każda klasa Telewizor, Telefonkom i inne muszą nadpisywać metodę void zapisz(Plik &P);

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