Prawdziwe oblicze Informatyki. Tysiące linijek kodu i kompilatory które nigdy nie wybaczają.
Awatar użytkownika

TheMediator95

Posty: 468
Rejestracja: 29 kwie 2010, 9:35
Kontakt:
    Windows 8.1 Internet Explorer

Post31 maja 2014, 18:30

Witam wszystkich zebranych! Nie przedłużając, przejdę do kodu:

Kod: Zaznacz cały

// DOSTĘP DO ZMIENNEJ "a" POPRZERZ DZIEDZICZENIE Z KLASY "A" class A { int a; }; class B : public A { int b; };

Kod: Zaznacz cały

// DOSTĘP DO ZMIENNEJ "a" POPRZEZ WSKAŹNIK DO OBIEKTU TYPU "A" class A { int a; }; class B { A* _a; int b; public: B() { _a = new A; } ~B() { delete _a; } };
Pytanie jest następujące, kiedy stosować dziedziczenie, a kiedy te rozwiązanie ze wskaźnikami?

Awatar użytkownika

PisarzKsiazkowicz

Moderator
Posty: 2205
Rejestracja: 27 sty 2010, 7:53
    Windows 8.1 Opera

Post31 maja 2014, 18:42

Dziedziczenie stosujesz, gdy chcesz zrobić nową klasę na bazie poprzedniej.
Wskaźniki stosujesz, gdy chcesz stworzyć obiekt klasy A wewnątrz obiektu klasy B.

Przykład, Lightbulb.
Stosuję dziedziczenie by zrobić klasę RosterListModel na bazie ListModel. W ten sposób mogę też zrobić inne takie bajery na bazie ListModel, w którym mam wspólne cechy dla wszystkich tych klas. W klasie MyXmppClient mam sobie wskaźnik do RosterListModel, dzięki czemu mogę sobie stworzyć i zarządzać listą kontaktów w tej klasie.

Z całym szacunkiem, ale takie przykłady omawiane na lekcjach są fallusowe.
ObrazekObrazek

Awatar użytkownika

TheMediator95

Posty: 468
Rejestracja: 29 kwie 2010, 9:35
Kontakt:
    Windows 8.1 Internet Explorer

Post31 maja 2014, 22:24

Czyli jak na razie nie powiedziałeś mi niczego czego bym jeszcze nie wiedział. Zobacz, na dobrą sprawę gdyby MyXmppClient dziedziczyłaby po RosterListModel to też "mogę sobie zarządzać listą kontaktów w tej klasie (RosterListModel )." Dlatego pytam się kiedy stosuje się jedno rozwiązanie, a kiedy drugie, które jest szybsze itd.
Z całym szacunkiem, ale takie przykłady omawiane na lekcjach są fallusowe.
Jakich lekcjach? :P

Awatar użytkownika

PisarzKsiazkowicz

Moderator
Posty: 2205
Rejestracja: 27 sty 2010, 7:53
    Series 60 Opera

Post01 cze 2014, 8:20

A widzisz, bo nie. Co jeśli chciałbym mieć kilka modeli w tej klasie? Dziedziczenie powoduje, że mam wszystkie funkcje i obiekty danej klasy w nowej, gdy przy wskaźniku robisz nowy obiekt wewnątrz swojej klasy.

Nie ma jednoznacznej odpowiedzi lepsze/gorsze, tak jak z rodzajami pętli. Po prostu stosuje się to w różnych sytuacjach.
ObrazekObrazek

Awatar użytkownika

TheMediator95

Posty: 468
Rejestracja: 29 kwie 2010, 9:35
Kontakt:
    Windows 8.1 Internet Explorer

Post01 cze 2014, 16:17

Co jeśli chciałbym mieć kilka modeli w tej klasie?
W C++ klasa pochodna może mieć więcej niż jedną klasę bazową, tak więc bez problemu jeśli klasa MyXmppClient dziedziczyłaby po kolejnym "modelu", to efekt byłby taki sam jak przy użyciu wskaźnika. Więc jeśli chodzi o widoczność elementów składowych klas to nie ma znaczenia którego sposobu się użyje.
Wydaje mi się że jest to kwestia dobrej reprezentacji rzeczywistości w programach. Na przykład klasa Ubiór nie powinna być klasą bazową dla człowieka, ponieważ człowiek wcale nie musi być ubrany. W przypadku kiedy człowiek nie jest ubrany przy dziedziczeniu marnuje się pamięć zarezerwowaną dla ubioru którego nie ma. Tak samo z klasą Ubiór, może zawierać obiekty innych klas takich jak: Buty, Spodnie, Czapki itd., wydaje się lepszy w tej sytuacji wskaźnik bo nie mogę założyć że każdy będzie nosił na przykład czapkę.
Dziedziczenie zakłada iż coś na pewno istnieje, natomiast tworzenie wskaźnika na własny typ wewnątrz nowego typu, zakłada że coś może istnieć lub nie. Ja właśnie tak odbieram to rozwiązanie, chociaż mogę się mylić, dlatego tutaj napisałem. Tak więc Pisarzu, co o tym myślisz?
Wydaje mi się że metoda wskaźnikowa jest wolniejsza podczas tworzenia obiektu, natomiast szybsza podczas odczytu i zapisu danych na utworzonym obiekcie.

Awatar użytkownika

bsystem

Zasłużony użytkownik
Posty: 652
Rejestracja: 03 lis 2010, 16:44
    Windows 8.1 Chrome

Post01 cze 2014, 16:24

Mediator95 - człowiek, który prosi o radę a potem sam się wymądrza na temat w kwestii którego prosił.
Spoilerpokaż
Asus n61v | c2d p7450 | GT 240m | 4GB DDR3 | 320GB | Windows 8.1 x64
Fujitsu Siemens Esprimo V5505 | C2D T7550 2,2GHz 4MB Cache L2 (Merom) | 4GB RAM DDR2| 120GB| Windows 8.1 x64
Pentium 4 |Pentium 4 3.0GHz (Prescott) | 1 GB RAM DDR1 | 60 GB |Windows 8 RTM
Toshiba Satellite 1400-503 | Celeron-S 1,33GHz (tualatin :hyhy:) | 768 MB SD-RAM | 40GB | Windows XP SP3
K6-2| AMD K6-2 300MHz | 64MB SD-RAM |1GB| Windows 2000 Fresh by Rublik
Serwer 'Sempik': AMD Sempron 2800+ | ASUS K8V-MX | 1024 MB RAM DDR1 | S3 Graphics DeltaChrome Pro IGP | 20GB + 500GB | Windows 2k8
Pentium 4 1,7 GHz| OEM Fujitsu | 512MB SD RAM| 40GB
Sempron 2200+ | jakieś mobo MSI | 128MB DDR | 40GB
Intel Pentium III Coppermine | mobo na intelu | 128MB SD RAM | 80GB
Sempron 2800+ | ASRock K8NF4G-SATA2 | 512MB DDR | 160GB RAID0
Pentium II | mobo na slot1 | 128MB SD RAM | 2GB


Komputery mniej lub bardziej kompletne:

Amilo M7400 | Pentium M 1,3 GHz (Banias)| 512 MB RAM | dysk zbrickowany | +15" CRT
iPhone 5c + Dell e6230

Awatar użytkownika

lolasher

Zasłużony użytkownik
Posty: 2387
Rejestracja: 10 paź 2008, 18:28
Lokalizacja: Zadupie pod Siedlcami ;)
Kontakt:
    Macintosh Safari

Post01 cze 2014, 16:29

Mediator, a zasadnicza różnica nie polega na dziedziczeniu konstruktorów i takich tam?

Awatar użytkownika

PisarzKsiazkowicz

Moderator
Posty: 2205
Rejestracja: 27 sty 2010, 7:53
    Windows 8.1 Opera

Post01 cze 2014, 17:39

W C++ klasa pochodna może mieć więcej niż jedną klasę bazową, tak więc bez problemu jeśli klasa MyXmppClient dziedziczyłaby po kolejnym "modelu", to efekt byłby taki sam jak przy użyciu wskaźnika. Więc jeśli chodzi o widoczność elementów składowych klas to nie ma znaczenia którego sposobu się użyje.
Lol nope.

Patrz.
Mam sobie klasę MyXmppClient, w której załóżmy, że jest RosterListModel i ChatsListModel.
Obie zawierają podobne funkcje i pododne dane, ale ChatsListModel zawiera dane dotyczące otwartych rozmów, zaś RosterListModel zawiera całą listę kontaktów. Jeśli użyłbym dziedziczenia, nie byłbym w stanie przechowywać obu osobnych list, you know?

Ale za to mogę zrobić na luzie wskaźnik roster i wskaźnik chats. :> Teraz mogę zrobić Q_PROPERTY, dzięki czemu będę mógł pobrać jedną listę po prostu w sposób xmppClient.roster i xmppClient.chats. Tego też nie mógłbym za bardzo zrobić korzystając z dziedziczenia.

bsystem() { this->approve(); }

lolasher, właśnie w tym rzecz. W momencie, gdy dziedziczysz, tworzysz klasę która opiera się na innej klasie, ma te same funkcje i wartości itd.

Jak już mówiłem, jeśli potrafisz kodzić, wiesz kiedy jedno ma sens, a kiedy drugie. To są dwie odrębne rzeczy i chociaż idealnie wpasowują się w Twój durny przykładzik, to w prawdziwym życiu nie ma tak łatwo.
ObrazekObrazek

Kto jest online

Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 1 gość