Dziedziczenie wielokrotne i zmienne protected

0

Witam
Napisałem taki program

#include <iostream>
#include <string>
using namespace std;
class Horse{
	string name;
//protected:

public:
	int age;
	Horse() {
		name="Dolly";
		age=10;
	}
	Horse(int a,string n) {
		age=a;
		name=n;
	}
	void show(){
		cout<<"I am "<<name<<" and I am "<<age<<" years old."<<endl;
	}
	virtual ~Horse() {
		cout << "Horse destructor... "<<endl; 
	}
};

class Bird{
	string name;
//protected:
	
public:
	int weight;
	Bird() {
		weight=8;
		name="angry";
	}
	Bird(int w,string n) {
		name=n;
		weight = w;
	}
	virtual ~Bird() {
		cout << "Bird destructor... "<<endl; 
	}
	void show(){
		cout << "I am "<<name<<" and I weight "<<weight<<" kg."<<endl; 
	}
};

class Pegasus : public Horse, public Bird{
	string name;	
public:
	
	Pegasus(Horse &h,Bird &b) {
		name="Gold";
		cout << "I am "<<name<<" and I weight "<<b.weight<< "kg"<<" and I am "<<h.age<<" years old"<<endl;
	}
	Pegasus() {
		 name="Gold";	 
	}
	~Pegasus() { 
		cout << "Pegasus destructor...  "<<endl; 
	}
	void show(){
		cout << "I am "<<name<<" and I weight "<<weight<< "kg"<<" and I am "<<age<<" years old"<<endl;
	}

};

int main(){
	Horse konik(22,"a");
	konik.show();
	Bird angry(10,"b");
	angry.show();
	Pegasus p(konik,angry);
	Pegasus s;
	s.show();
	return 0;
} 

Wszystko działa, tylko chciałbym aby zmienna age(klasa Horse) i __weight __(klasa bird) były ustawione jako protected.
Jednak wtedy dostaję błąd w konstruktorze który przyjmuje za parametry dwie klasy:cannot access protected member declared in class
Dlaczego tak się dzieje? Przecież pola są protected czyli mogę używać ich w innych klasach (w tym wypadku pegasus)

1

kompilator mówi ci że nie wolno ci pobrać WARTOŚCI tych pól bo są prywatne/chronione. Będziesz miał te pola dostępne w klasie pochodnej, ale zauważ że problem jest z wyciągnięciem ich wartości z innych obiektów. Zrób im ładne akcesory i już.

0

Akcesory??
Czyli mam napisać f która zwraca wartość tego elementu? (W takim wypadku będe musiał napisać dodatkowo 2 funkcje.) łatwiej jest zmienić jako public.

Próbowałem dać Pegasus(Horse &h,Bird &b) jako przyjaciela do klasy Horse i Bird, Jednak dostawałem błąd bo te klasy nie były jeszcze zdeklarowane.. czy jest jakieś rozwiązanie?

1

Hm? Friend musi działać.

friend class Pegasus;
1

@xamrex teoretycznie łatwiej ci to zmienić na public, fakt. Ale myśl perspektywicznie. Wygodnie jest stosować enkapsulację (czyli chowanie szczegółów implementacji za pewnym interfejsem) bo dzięki temu zmiany w implementacji nie wpływają na zmiany w kodzie który z naszych klas korzysta.
Załóżmy że nagle postanowiłeś ze zamiast zmiennej "age" przechowującej ilość lat w Horse chciałbyś mieć z jakiegoś powodu informacje o wieku przechowywane w pewnej strukturze która pozwala przechowywać ilość dni, miesięcy i lat. Gdybyś wyrzucił zmienną age i wrzucil taką strukturę to okazuje się że musisz dokonać zmian we wszystkich kodach które korzystały z Horse i pobierały wartość age jako wartość pola, bo teraz trzeba by tam zamiast tego wstawić pobieranie wartości ze struktury.
Gdybyś zamiast tego miał metodę getAge() tego problemu by nie było, bo zmieniłbyś tylko implementację metody a wszystko inne działałoby tak jak powinno.

0

dzięki
nie wiedzałem że można dać friend na klase

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