Dziedziczenie klas a operator przeładowany <<

0

Witam, posiadam klasę Figura a w niej operator << wyświetlający elementy klasy.

Mam utworzyć klasę dziedziczącą Koło po klasie Figura i w niej również zawrzeć operator <<

Jednak otrzymuję błąd, iż ten operator nie posiada praw do tych zmiennych.

Error 1 error C2248: 'Figura::nazwa' : cannot access private member declared in class 'Figura' c:\users\paweł kreis\documents\visual studio 2013\projects\lab3\lab3\source.cpp 53 1 Lab3
Error 2 error C2248: 'Figura::pole' : cannot access private member declared in class 'Figura' c:\users\paweł kreis\documents\visual studio 2013\projects\lab3\lab3\source.cpp 53 1 Lab3

Same klasy ze sobą się przyjaźnią

Poniżej kod:

#include <iostream>
#include <string>

using namespace std;

class Kolo;
class Kwadrat;
class Figura
{
public:
	Figura(string name = "figura" , double pl = 5)
	{
		nazwa = name;
		pole = pl;
		ilosc++;
	}
	virtual ~Figura()
	{
		ilosc--;
	}
	friend ostream& operator<< (ostream &wyjscie, Figura const& fi)
	{
		wyjscie << "Nazwa figury: " << fi.nazwa << " Pole: " << fi.pole << endl;
		return wyjscie;
	}
private:
	string nazwa;
	double pole;
	static int ilosc;
public:
	static int IleElementow()
	{
		cout << ilosc;
		return ilosc;
	}
	friend class Kolo;
	friend class Kwadrat;
};

class Kolo : public Figura
{
	Kolo(string name = "figura", double pl = 5, double pr = 2)
	{
		nazwa = name;
		pole = pl;
		promien = pr;
		ilosc++;
	}
public:
	friend ostream& operator << (ostream &wyjscie, Kolo fi)
	{
		wyjscie << "Nazwa figury: " << fi.nazwa << " Pole: " << fi.pole << endl;
		return wyjscie;
	}
private:
	double promien;
};

class Kwadrat : public Figura
{
	friend class Figura;
public:
	int sprawdz()
	{
		cout << nazwa;
	}
private:
	double promien;
};


int Figura::ilosc = 0;

int main()
{
	Figura f1("kwadrat", 4);
	Figura f2("kolo", 4);
	Figura f3;
	f1.IleElementow();

	cout << f1;
	
}

Jak dokonać zatem by to zadziałało?

2

Problem jest taki, że prywatne składowe nie są dziedziczone. Rozwiązanie (bardzo brzydkie), zadeklaruj je w klasie bazowej jako chronione (protected).

Rozwiązanie ładniejsze, ale najpierw kilka rzeczy:
#Nie używaj friend nigdy (a przynajmniej na etapie początkującego).
#W obecnym kodzie, nie ma jak utworzyć obiektu klasy Kolo.
#Figura nie powinna się zajmować liczeniem ilości obiektów. Do tego służą kolekcje.

Teraz poprawiony trochę kod (a właściwie to przykład).

#include <string>
#include <cmath>
#include <vector>
#include <iostream>

class Shape {
public:
  Shape(const std::string name): _name(name) { ; }

  std::string name() const { return _name; }

  virtual double area() const = 0;

private:
  const std::string _name;
};

class Circle : public Shape {
public:
  Circle(double r): Shape("Circle"), _r(r) { ; }

  double area() const override {
    return M_PI * _r * _r;
  }

private:
  const double _r;
};

std::ostream& operator<<(std::ostream& out, const Shape& s) {
  return out << "Nazwa: " << s.name() << ", pole: " << s.area();
}

int main() {
  std::vector<Shape*> shapes = { new Circle(12.5), new Circle(18.5) };
  for(unsigned i = 0; i < shapes.size(); ++i) {
    std::cout << *shapes[i] << "\n";
  }

  for(unsigned i = 0; i < shapes.size(); ++i) {
    delete shapes[i];
  }
  return 0;
}

http://ideone.com/9ydFVv

I uwaga mała. Jak już będziesz bardziej obyty w C++, to wypada zamienić std::vector<Shape*> na std::vector<std::shared_ptr<Shape>>.

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