W książce c++ dla każdego jest taki właśnie rozdział. Wszystko jest w nim dla mnie jasne z wyjątkiem jednego. Dlaczego autor uważa, że następująca definicja funkcji czyni ją funkcja klasy rectangle a nie point, skoro na początku definicji tej funkcji jest właśnie słowo kluczowe point.
[code]
class point
{
coś tam coś tam
}
class rectangle
{
...coś tam coś tam...
public:
point "i tutaj definicja funkcji"
private:
point "jakiś obiekt"...
}
[/code]
Wydawało mi się,że właśnie to słowo kluczowe "point" oznacza zdefiniowanie jakiegoś obiektu klasy point w klasie rectangle. Autor natomiast twierdzi, że obiekt "i tutaj definicja funkcji" jest obiektem klasy rectangle i że ten obiekt nie ma dostępu do prywatnych obiektów klasy point. No to po jakiego czorta napisane jest słowo kluczowe "point" przed tym obiektem ?
jest to definicja metody (lub jak ty to nazywasz funkcji), która należy do klasy rectangle, ale zwraca typ point
class B {};
class A
{
private:
B obiekt;
B metoda() {}
};
o zmiennej obiekt, mogę mówić, że jest obiektem klasy B należącym do klasy A.
klasa A i B są czystą abstrakcją, dopiero:
A obiekt;
lub:
A* obiekt = new A;
tworzy nam obiekt klasy A
na przykładzie.
Punkt (2D) jest to para współrzędnych:
class Punkt
{
public:
float x,y;
};
trójkąt jest to figura, którą można opisać zestawem trzech punktów
class Trojkat
{
public:
Punkt a,b,c;
};
punkty a,b,c są punktami, ale należą do trójkąta
Pozwól, że odrobinkę przerobię ten kod,by wyjaśnić czego nie rozumiem.
krwq napisał(a)
na przykładzie.
Punkt (2D) jest to para współrzędnych:
class Punkt
{
public:
float c(); //akcesor, który ma dostęp do cosia
float x,y;
private:
float coś;
};
trójkąt jest to figura, którą można opisać zestawem trzech punktów
class Trojkat
{
public:
Punkt a,b,c; //zdaniem autora żaden z punktów a b c nie może mieć dostępu do "cosia".
private:
Punkt cokolwiek; //jego zdaniem wolno napisać:"cokolwiek.c()",bo obiekt cokolwiek jest obiektem klasy Punkt
};
punkty a,b,c są punktami, ale należą do trójkąta
Okej, więc zdaniem autora obiekt cokolwiek jest obiektem klasy Punkt i dzięki temu, gdy napiszę cokolwiek.c(), to mam dostęp do prywatnego obiektu "coś" klasy Punkt. Zatem z jakiego powodu obiekt "cokolwiek" mam traktować jako należący do klasy Punkt a już "a,b,c" muszę traktować jako należące do klasy Trójkąt? Przecież słowo Punkt znajduję się zarówno przed "a,b,c" jak i przed "cokolwiek". Tu właśnie mam zagwostkę,bo logika mi podpowiada, iż jeżeli a,b,c należą do trójkąta (bo są zdefiniowane w klasie Trójkąt), to obiekt "cokolwiek" także powinien należeć do klasy Trójkąt;-))
Wydaje mi się, że wiem o co chodziło autorowi.
- Zarówno a, b, c jak i cokolwiek są obiektami klasy Punkt należącymi do klasy Trójkąt.
- Cos jest prywatną składową klasy Punkt - tylko funkcje składowe (metody) klasy punkt mogą mieć do niej dostęp. Normalne funkcje i metody innych klas - nie.
- W metodzie klasy trójkąt nie można, więc napisać a.cos, b.cos, c.cos, czy cokolwiek.cos ponieważ klasa Trójkąt != klasa Punkt.
- Należy więc użyć akcesora c pisząc np.: a.c() lub cokolwiek.c().
Mam nadzieję, że już wszystko jasne.
PS. Także jestem początkujący, więc moich słów nie należy traktować jak wyroczni. Jeśli się pomyliłem lub sam czegoś nie zrozumiałem proszę o poprawienie mnie przez użytkowników z większym doświadczeniem.
Zarówno obiekty a,b,c oraz cokolwiek są obiektami klasy Punkt i mogą istnieć zarówno osobno, jak i mogą należeć do innej klasy, dla powyższego przykładu: klasa Trójkąt zawiera 3 publiczne obiekty klasy Punkt i 1 prywatny obiekt również tej klasy.
Mógłbyś przytoczyć fragment z książki, który o tym mówi? Gdyż nie widzę tu żadnej niejasności.
Najprościej mówiąc pola prywatne mogą być użyte tylko i wyłącznie przez funkcje klasy, do których te pola należą.
Przypuśćmy taką sytuację:
class Okno
{
public:
int szerokosc() const {return itsSzerokosc;}
private:
int itsSzerokosc;
};
class Dom
{
public:
int szerokoscOkna() const;
private:
Okno oknoKuchni;
};
int Dom::szerokoscOkna() const
{
// funkcja ta ma dostęp do wszystkich zmiennych prywatnych i publicznych swojej klasy
// klasa Dom ma dostęp do obiektu okno, czyli może operować na tym obiekcie
// return oknoKuchni.itsSzerokosc; ---- błąd --- itsSzerokosc jest zmienną prywatną klasy Okno dlatego nie możemy odwołać się do niej za pomocą "." w innych funkcjach niż w funkcjach tej klasy
return oknoKuchni.szerokosc(); // dlatego używamy publicznego akcesora
};
Wydaje mi się, że ten fragment zilustruje o co chodzi, po prostu musisz wiedzieć, że jak sama nazwa wskazuje pola prywatne są prywatne i nie wolno ich bezpośrednio używać w innych miejscach niż funkcje danej klasy.
Pytanie jest w komentarzu niżej tzn. tam, gdzie jest implementacja konstruktora Rectangle. Ogólnie rozumiem o co chodzi w tym temacie, ale pytanie mam właśnie odnośnie jednego szczegółu.
[quote]
class Point {
public:
void SetX (int x) { itsX=x; }
void SetY (int y) { itsY=y; }
int GetX() const { return itsX; }
int GetY() const { return itsY; }
private:
int itsX;
int itsY;
};
class Rectangle {
public:
Rectangle(int top,int left,int bottom, int right);
~Rectangle(){};
int GetTop() const { return itsTop; }
int GetLeft() const { return itsLeft; }
int GetBottom() const {return itsBottom;}
int GetRight() const { return itsRight; }
Point GetUpperLeft() const {return itsUpperLeft;}
Point GetLowerLeft() const {return itsLowerLeft;}
Point GetUpperRight() const {return itsUpperRight;}
Point GetLowerRight() const {return itsLowerRight;}
void SetUpperLeft(Point Location) { itsUpperLeft=Location;}
void SetLowerLeft(Point Location) {itsLowerLeft=Location;}
void SetUpperRight(Point Location) {itsUpperRight=Location;}
void SetLowerRight(Point Location) {itsLowerRight=Location;}
void SetTop(int top) { itsTop=top;}
void SetLeft(int left){ itsLeft=left;}
void SetBottom(int bottom) {itsBottom=bottom;}
void SetRight(int right) {itsRight=right;}
int GetArea() const;
private:
Point itsUpperLeft;
Point itsLowerLeft;
Point itsUpperRight;
Point itsLowerRight;
int itsTop;
int itsLeft;
int itsBottom;
int itsRight;
};
Rectangle::Rectangle(int top,int left, int bottom, int right)
{
itsTop=top;
itsLeft=left;
itsBottom=bottom;
itsRight=right;
itsUpperLeft.SetX(left); //W klasie Point nie ma ani obiektu itsTop ani parametru top
itsUpperLeft.SetY(top); //rozumiem, że top jest parametrem Rectangle, ale...
itsUpperRight.SetX(right); //skad mam miec pewność,że itsTop jest "jakoś"
itsUpperRight.SetY(top); //powiązany z SetX, skoro SetX zawiera parametr int x?
//Przecież w definicji Setx mam: SetX(int x){itsX=x}
itsLowerLeft.SetX(left); //A tutaj każą mi napisać SetX(top);
itsLowerLeft.SetY(bottom); //to samo z right,bottom i left.
itsLowerRight.SetX(right);
itsLowerRight.SetY(bottom);
}
int Rectangle::GetArea() const
{
int Width=itsRight-itsLeft;
int Height=itsTop-itsBottom;
return (Width*Height);
}[\quote]
X obj;
- obiekt klasy X? TAK. Obiekt obj
jest typu X
.
X func(int foo);
- funkcja klasy X? NIE!!!!!!!!! Funkcja func
nie jest typu X
, jest typu funkcyjnego X (*)(int)
Pisząc "funkcja klasy X" chodziło o funkcję będącą składnikiem klasy X.
Podsumowując:
- mówiąc o obiekcie, że jest danej "klasy" mamy na myśli typ obiektu (jaka jest jego klasa)
- mówiąc o funkcji/metodzie, że jest danej "klasy" mamy na myśli to, że jest to składnik tej klasy (do jakiej klasy należy)
Tak jak "jaja klasy pierwszej" vs. "uczeń klasy pierwszej". Raz mówimy o jakości podmiotu, innym razem o przynależności.
Aby uniknąć niejednoznaczności raczej powinno się mówić "obiekt typu X" niżeli "obiekt klasy X".
itsUpperLeft.SetX(left); //W klasie Point nie ma ani obiektu itsTop ani parametru top
itsUpperLeft.SetY(top); //rozumiem, że top jest parametrem Rectangle, ale...itsUpperRight.SetX(right); //skad mam miec pewność,że itsTop jest "jakoś"
itsUpperRight.SetY(top); //powiązany z SetX, skoro SetX zawiera parametr int x?
//Przecież w definicji Setx mam: SetX(int x){itsX=x}
itsLowerLeft.SetX(left); //A tutaj każą mi napisać SetX(top);
itsLowerLeft.SetY(bottom); //to samo z right,bottom i left.
Moim zdaiem nie rozumiesz czym jest nazwa parametru funkcji. Sama nazwa (prawie) nie ma znaczenia. Pomiędzy nazwą zmiennej przekazywanej do funkcji a nazwą parametru funkcji (pomijając typ) nie ma żadnego związku.
Zatem można przekazywać zmienną o dowolnej nazwie, której typ odpowiada typowi parametru, albo może być do niego przekształcony (konwersja).