Autor Wątek: kompozycja, agregacja ich odpowiednik w c++  (Przeczytany 958 razy)

Offline Montjet

  • Użytkownik

# Styczeń 15, 2017, 11:46:20
Witam,
co jest odpowiednikiem agregacji, kompozycji w c++?
Agregacja: vector<Klasa*>
Kompozycja: Klasa klasa, vector<Klasa>
Czy dobrze jest to przyporządkowane? coś dodać?
Wiem (jestem pewien), że referencja i wskaźnik: Klasa&, Klasa* to asocjacja (bez strzałek - linia ciągła).

Co w przypadku szablonu: "template<class T> class ..." - co to jest?
« Ostatnia zmiana: Styczeń 15, 2017, 13:01:08 wysłana przez Montjet »

Offline Mr. Spam

  • Miłośnik przetworów mięsnych

Offline Lerhes

  • Użytkownik

# Styczeń 15, 2017, 22:21:05
Cześć,

Odpowiem jak ja rozumiem te pojęcia - mam nadzieję, że niczego nie pomieszam.
Żeby od czegoś zacząć, to zacznijmy od opisu na:
https://pl.wikipedia.org/wiki/Agregacja_(programowanie_obiektowe)

Dla mnie agregacja, to zawieranie. Czyli jedna klasa zawiera inną. Np:
class Okladka{
string tytul;
string autor;
bool czyGruba;
Color kolorOkladki;
void spal() {}
};

class Ksiązka {
Okladka okladka;
int liczbaStron;
};

W przypadku powyżej, z agregacją mamy do czynienia w klasie Okladka i w klasie Ksiazka. Klasa Okladka agreguje (zawiera) dwa obiekty klasy string i jeden obiekt klasy Color . Można powiedzieć także, (parafrazując Wikipedię) że klasa Okladka składa się z obiektów string i Color.
Podobna sytuacja jest z klasą Ksiazka - zawiera ona klasę Okladka (czyli mamy agregację).

Dodane: Na marginesie: Czy relacja która występuję między Ksiazka a Okladka to mogła by być kompozycja (specjalny przypadek agregacji) - oczywiście że tak. To zależy czy dopuszczamy możliwość tworzenia obiektów okładka bez obiektu książka.... -> proszę czytać dalej.

Teraz jeżeli chodzi o kompozycję - to jest to agregacja ale obiekty agregowane nie mogą istnieć bez obiektu głównego. Przykładów można wymyślić dużo - jak dla mnie tutaj bardziej zależy od kontekstu.
Np:
class KanalTelewizyjny
{
string nazwa;
};
class Telewizor{
vector<KanalTelewizyjny> kanaly;
};

W tym przypadku mamy do czynienia z agregacją ale i kompozycją. Klasa KanalTelewizyjny jest stworzona z obiektu klasy string - agregacja. Klasa Telewizor zawiera wiele obiektów klasy KanalTelewizyjny - agregacja. Natomiast ta druga agregacja jest też kompozycją - Telewizor posiada obiekty klasy KanalTelewizyjny - ale obiekty KanalTelewizyjny  nie mogą istnieć poza klasą Telewizor.

Tutaj ważna jest sprawa twojego konkretnego przypadku. Jeżeli obiekty klasy KanalTelewizyjny mogą być tylko agregowane przez klasę Telewizor - a bez niej nie ma sensu tworzyć obiektów klasy KanalTelewizyjny   - wtedy mamy kompozycję. Gdyby w twojej aplikacji miało to sens - wtedy miałbyś zwykłą agregację - nie kompozycję.
Jak dla mnie to trzeba najbardziej podkreślić - agregacja, kompozycja i inne relacje - służą do określenia właśnie relacji między obiektami - jeżeli projektujesz swoją aplikację i chcesz zaznaczyć, że jedna klasa zawiera inną klasę - rysujesz pusty romb - wszyscy wiedzą, że to agregacja i że jedna klasa będzie zawierać obiekty drugiej klasy. Gdybyś do tego chciał podkreślić, że obiekty tej drugiej klasy nie mogą istnieć bez obiektów tej pierwszej klasy (bo nie miało by to większego sensu) - to rysujesz romb wypełniony.
Inny przykład na kompozycję ze świata GUI (Graficznego Interfejsu Użytkownika), który wydaje mi się równie dobry: Relacja która łączy przycisk i okno to właśnie kompozycja. Czyli okno zawiera w sobie przyciski. Czy przycisk może istnieć bez okna? - Nie. Czy okno może istnieć bez przycisków - tak. Ja taką relację oznaczyłbym właśnie wypełnionym rombem (kompozycją).
Uwaga: Gdyby w twoim konkretnym przypadku było możliwe istnienie przycisku bez okna - ok u Ciebie mogła by być to agregacja. W moim przypadku użyłbym kompozycji bo wykluczam istnienie przycisku bez okna. Żeby to podkreślić używam właśnie relacji która się nazywa kompozycja.

Natomiast nie podoba mi się twoje rozumowanie:
Cytuj
Wiem (jestem pewien), że referencja i wskaźnik: Klasa&, Klasa* to asocjacja (bez strzałek - linia ciągła).
Relacje między obiektami to jak dla mnie jedna sprawa, a czy to będą wskaźniki czy referencje to zupełnie coś innego. Nie dostrzegam tutaj związku - że wskaźnik to na pewno asocjacja - skąd taki tok rozumowania?
Dodane: Może doprecyzuję - ok, jak masz referencję na klasę czy wskaźnik na klasę - to faktycznie jedna klasa będzie zawierać inną - trudno żeby mieć tu coś innego. Więc zgodzę się, że to będzie wtedy agregacja (a nie na przykład relacja dziedziczenia - rodzic - potomek). Ale równie dobrze mogła by to być kompozycja. Wydaje mi się, że są to dwa zupełnie inne światy - jak rozmawiamy o agregacji czy kompozycji - rozmawiamy w kontekście relacji między obiektami - a nie czy będziemy używać wskaźników czy referencji...

Na koniec pytanie o szablon: "template<class T> class ..." co to jest? Ja bym odpowiedział, zależy co ten szablon robi. 

Tak ja rozumiem temat - jeżeli coś pokręciłem to proszę o sprostowanie. Przykłady były wymyślane na kolanie i nie do końca mogą być trafione :P

Pozdrawiam,
Lerhes
« Ostatnia zmiana: Styczeń 15, 2017, 22:36:46 wysłana przez Lerhes »

Offline Reg

  • Administrator
    • Adam Sawicki - Home Page

# Styczeń 20, 2017, 01:12:45
Ja bym dodał jeszcze przypadek inteligentnego wskaźnika - np. kiedy Klasa2 zawiera std::unique_ptr<Klasa1>. Co to jest wtedy?

Moim zdaniem kluczowe jest tu określenie własności.

Jeśli obiekt klasy Klasa2 jest właścicielem obiektu klasy Klasa1 - co można poznać przede wszystkim po tym, że on go tworzy oraz usuwa z pamięci - to mamy tu do czynienia z agregacją lub kompozycją, obojętne czy w C++ zrealizujemy to za pomocą wskaźnika inteligentnego, czy zwykłego Klasa1* z alokacją przez operator new i zwalnianiem przez operator delete.

Natomiast jeśli obiekt Klasa2 przechowuje wskaźnik lub referencję do obiektu Klasa1, ale stworzył i zwolni go zupełnie inny obiekt (trzeba wtedy świadomie kontrolować jego czas życia, żeby przypadkiem nie odwołać się do już zwolnionej pamięci), wtedy mamy do czynienia z asocjacją (bez strzałek).