Klasy korzystające z siebie nazwajem

0

Proste pytanie - co jest nie tak? Wiem, że mogę umieścić klasy w dwóch plikach nagłowkowych, wiem też, że tak powinno się robić, ale kazano na uczelnie zrobić w jednym, to robie w jednym.

#include <iostream>
using namespace std;

class Vector;

class Point {
private:
	double _x;
	double _y;
public:
	void move (Vector &V) volatile {
		_x = V._b._x - V._a._x + _x;
		_y = V._b._y - V._a._y + _y;
	}
};



class Vector {
private:
	Point _a;
	Point _b;
public:
	friend class Point;

};



int main() {
	// your code goes here
	return 0;
}
prog.cpp: In member function ‘void Point::move(Vector&) volatile’:
prog.cpp:12:9: error: invalid use of incomplete type ‘class Vector’
   _x = V._b._x - V._a._x + _x;
         ^
prog.cpp:4:7: error: forward declaration of ‘class Vector’
 class Vector;
       ^
prog.cpp:12:19: error: invalid use of incomplete type ‘class Vector’
   _x = V._b._x - V._a._x + _x;
                   ^
prog.cpp:4:7: error: forward declaration of ‘class Vector’
 class Vector;
       ^
prog.cpp:13:9: error: invalid use of incomplete type ‘class Vector’
   _y = V._b._y - V._a._y + _y;
         ^
prog.cpp:4:7: error: forward declaration of ‘class Vector’
 class Vector;
       ^
prog.cpp:13:19: error: invalid use of incomplete type ‘class Vector’
   _y = V._b._y - V._a._y + _y;
                   ^
prog.cpp:4:7: error: forward declaration of ‘class Vector’
 class Vector;
       ^
0

Może zastanów się nad takim rozwiązaniem:

#include <iostream>
using namespace std;

class Point;
class Vector
  {
   private:
   Point _a,_b;
   public:
   const Point &a()const { return _a; }
   const Point &b()const { return _b; }
  };
 
class Point
  {
   private:
   double _x,_y;
   public:
   Point():_x(0),_y(0) {}
   Point(double _x,double _y):_x(_x),_y(_y) {}
   Point operator+(const Point &p)const { return Point(x+p.x,y+p.y); }
   Point &operator+=(const Point &p) { *this=operator+(p); return *this; }
   Point operator-(const Point &p)const { return Point(x-p.x,y-p.y); }
   Point &operator-=(const Point &p) { *this=operator-(p); return *this; }
   Point &operator<<(const Vector &V) volatile { operator+=(V.b()-V.a()); return *this; } // zamiast move
  };
0

Sęk w tym, że mam dokładnie sprecyzowane funkcje, które mam zaimplementować. W każdym razie dzięki - problem już rozwiązany.
Swoją drogą - czym jest

const Point &a()const { return _a; }

Bezargumentowa funkcja (możliwa do wykonania na obiektach stałych) "a", która zwraca referencje na stałą typu Point.
Po co to pierwsze const? Nie rozumiem, w jaki sposób można to modyfikować.

0

Jeżeli funkcja zwraca const & to np. nie wywołasz na tym zwróconym obiekcie funkcji, która nie jest const. Po prostu nie będzie można zmodyfikować tego, do czego odnosi się referencja.

0

Okej, rozumiem. W tym jednak przypadku:

ostream & operator << (ostream &out, const Vector &A) {
	out<<A._a<<' '<<A._b;
	return out;
}

jest to zbędne, prawda?

0

Lepiej zrób tak:

ostream & operator << (ostream &out, const Vector &A) { return out<<A.a()<<' '<<A.b(); }

zamiast dodawania operatora jako friend

0

Dlaczego tak będzie lepiej? Rozumiem, że cały czas dodałbyś funkcje zwracające współrzędne punktu. Założmy, że użytkownik tego nie potrzebuje. Wciąż byś tak to zrobił?

0
annn napisał(a):

Okej, rozumiem. W tym jednak przypadku:

ostream & operator << (ostream &out, const Vector &A) {

jest to zbędne, prawda?

Zdefiniowanie zwracanej wartości jako const ostream& byłoby w tym przypadku błędne (a nie zbędne). Bo chcesz móc modyfikować zwrócony obiekt.

0
annn napisał(a):

Dlaczego tak będzie lepiej? Rozumiem, że cały czas dodałbyś funkcje zwracające współrzędne punktu. Założmy, że użytkownik tego nie potrzebuje. Wciąż byś tak to zrobił?

Już dwie metody tego potrzebują, move oraz operator przesunięcia więc prawdopodobnie będzie tego więcej.
Użytkownikiem tych klas jest programista, jak są to metody online to nawet nie zostaną wygenerowane kompilatorem o ile nie zostaną gdzieś użyte, zaś od przybytku głowa nie boli.
friend - to niezbyt dobry kierunek.

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