Definiowanie klasy w klasie

0

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 ?

0

jest to definicja metody (lub jak ty to nazywasz funkcji), która należy do klasy rectangle, ale zwraca typ point

0
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

0

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

0

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;-))

0

Wydaje mi się, że wiem o co chodziło autorowi.

  1. Zarówno a, b, c jak i cokolwiek są obiektami klasy Punkt należącymi do klasy Trójkąt.
  2. 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.
  3. 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.
  4. 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.

0

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.

0

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.

0

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]

0

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".

0

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).

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