• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Polimorficzny wskaźnik i wiele funkcji

Object Storage Arubacloud
0 głosów
1,029 wizyt
pytanie zadane 23 grudnia 2015 w C i C++ przez niezalogowany
Witam, chciałbym się zapytać czy warto zrobić w jednej abstrakcyjnej klasie wiele funkcji wirtualnych czy zrobić na każdą funkcję zrobić osobną??

3 odpowiedzi

0 głosów
odpowiedź 23 grudnia 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)
wybrane 23 grudnia 2015
 
Najlepsza

Odwołując się do Twojego kodu

class Komponent
{
    virtual void dodaj()=0;
    virtual void usun()=0;
    virtual void zmien()=0;
};

Jeżeli każda klasa, która dziedziczy po Komponent będzie posiadała swoją własną, unikalną realizację funkcji dodaj, usun oraz zmien, to nie ma w tym nic złego. Po prostu chcesz mieć kilka typów obiektów, na które będziesz mógł pokazać tym samym wskaźnikiem.

Funkcje będą inaczej napisane dla innych klas dziedziczących i wygląda to okej.

Jeżeli zastanawiasz się czy warto zrobić osobną klasę na każdą funkcję wirtualną, to masz na myśli takie cudo:?

class Komponent1
{
    virtual void dodaj()=0;
};

class Komponent2
{
    virtual void usun()=0;
};

class Komponent3
{
    virtual void zmien()=0;
};

A potem tworzyć kolejne 3 klasy dziedziczące po Komponent1, 2 i 3? Takie rozwiązanie wydaje się bez sensu. Na pewno Ty również widzisz to, prawda?
Jedna klasa abstrakcyjna może zawierać kilka wirtualnych funkcji. Nie ma z tym problemu. Rozdzielanie tego na osobne klasy i wymyślanie dla nich nazw, to byłaby udręka :-)

komentarz 23 grudnia 2015 przez niezalogowany

Na pewno Ty również widzisz to, prawda? 

Prawda :)

To teraz jeszcze jedno bo mam 15 klas (każda klasa w osobnym pliku) i teraz jest tak: czy muszę klasę Komponent muszę dawać do osobnego pliku, i te klasę (Komponent) podpiąć pod każdą inną klasę która dziedziczy z tej wirtualnej klasy??

komentarz 23 grudnia 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)

Powinno się umieścić w osobnym pliku klasę abstrakcyjną oraz w osobnych plikach wszystkie klasy po niej dziedziczące.

Będziesz musiał w każdym pliku klasy, która dziedziczy, dołączyć nagłówek klasy abstrakcyjnej.

Gdybyś się zastanawiał dlaczego nie umieścić wszystkich klas, które dziedziczą po "Komponent" w tym samym pliku razem z klasą "Komponent". Odpowiedź jest prosta: bo zrobi się duży bałagan. Jeżeli klas będzie dużo albo będą one rozbudowane, to jeden plik *.cpp tego nagłówka zamieni się w kilkuset linijkowego olbrzyma.
Nawigacja po pliku nagłówkowym, w którym są umieszczone deklaracje kilku klas też nie jest wygodna.

Klasa abstrakcyjna może nawet nie posiadać żadnej funkcji niewirtualnej, a w takiej sytuacji może również znajdować się tylko w pliku nagłówkowym. W pliku *.cpp nie ma za bardzo co dla niej definiować. Ewentualnie jakieś funkcje statyczne lub zmienne statyczne.

Oczywiście są wyjątki kiedy 2 klasy można umieścić w jednym pliku. Są to na przykład sytuacje, gdzie klasa 'A' zawiera w sobie obiekt klasy 'B'.

class B
{
public:
	int n;
	B( int x )
		:n( x ) {}
};

class A
{
public:
	B obiekt;
	A( int x )
		:obiekt( x ) {}
};

W powyższym przykładzie klasa 'A' zawiera obiekt klasy 'B' ALE! Klasa 'B' nie posiada konstruktora domyślnego, więc musimy sami uruchomić konstruktor z odpowiednim parametrem dla obiektu "obiekt" i to właśnie robię w linijce 14. Robimy to na liście inicjalizacyjnej konstruktora klasy 'A'.

Są też popularne takie praktyki, aby klasę 'B' definiować wewnątrz klasy 'A' pod etykietą "private". Dzięki temu, możemy wewnątrz klasy 'A' (dla własnej wygody) korzystać z klasy 'B', tworzyć sobie obiekty tej klasy, ale klasa 'B' pozostaje przy tym niewidoczna dla świata zewnętrznego.

class A
{
private:
    class B
    {
    public:
        int n;
        B( int x )
            :n( x ) {}
    };
public:
    B obiekt;
    A( int x )
        :obiekt( x ) {}
};

Powyższy kod zawiera właśnie zagnieżdżoną definicję klasy wewnątrz innej klasy. Należy jednak zwrócić uwagę na to, że definicja klasy zagnieżdżonej musi być nad deklaracją obiektu tej klasy. To znaczy, że najpierw na górze musiałem napisać całą definicję klasy 'B' a dopiero później mogłem stworzyć w 12 linijce: "B obiekt;".
Inaczej by nie zadziałało, bo kompilator musi wiedzieć czym jest "B" :-)

komentarz 23 grudnia 2015 przez niezalogowany
YYY... Tak.

Myślę, że wszystko zrozumiałem, a jak coś to przeczytam jeszcze raz. Więc zdefiniuję Komponent w każdej klasie (po prostu podepnę), oraz tam gdzie jest funkcja main.
komentarz 23 grudnia 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)

Dokładnie tak musisz zrobić. Taką hierarchię jaką napisałeś.

Może dla pewności wyślę mój wspaniały rysunek z painta, abyś był już pewny w 100% jak podołączać te nagłówki :-D

komentarz 23 grudnia 2015 przez niezalogowany
i w pliku main.cpp będzie widoczna klasa Komponent??
komentarz 23 grudnia 2015 przez Sebastian Fojcik Nałogowiec (43,020 p.)
Po dołączeniu klasa1 lub klasa2 lub klasa3, owszem, będzie widoczna. Wynika to z faktu, że dyrektywę #include można zagnieżdżać. To znaczy, że jeśli w "main.cpp" zapiszemy "#include "klasa1.h"", to przed kompilacją preprocesor wklei nam do maina w miejsce "#include "klasa1.h"" wszystko co zawiera plik "klasa1.h".
A co zawiera ten plik? Ano, zawiera linijkę "#include "Komponent.h"", tak więc ta linijka również pojawi się w main.cpp. A jeżeli ta linijka się pojawi w main, to znaczy, że w main pojawi się definicja klasy Komponent.

Oczywiście nic nie stoi na przeszkodzie, aby dołączyć sobie do maina "Komponent.h".

Jeśli nadal nie wiesz dlaczego bez dołączania "Komponent.h" klasa "Komponent" będzie widoczna, to poczytaj jak działa dyrektywa #include
http://cpp0x.pl/dokumentacja/preprocesor/include/1120
oraz czym jest preprocesor :-P
komentarz 23 grudnia 2015 przez niezalogowany
Rozwiązałeś w 100% mój problem, dzięki wielkie za pomoc i daję Ci ptaszka :) Wesołych Świąt :)
0 głosów
odpowiedź 23 grudnia 2015 przez event15 Szeryf (93,790 p.)
Nie do końca kumam o co Ci chodzi. Ale coś czuję, że odpowiedź brzmi "to zależy".

Kiedy masz klasę, która ma same virtuale to jest to interfejs. To ma więcej wspólnego z polimorfizmem później niż klasy abstrakcyjne. Chociaż to ma znaczenie większe w językach, w których rozróżnia się implementację od dziedziczenia.
komentarz 23 grudnia 2015 przez niezalogowany

Ok, chodzi mi o to:

class Komponent
{
    virtual void dodaj()=0;
    virtual void usun()=0;
    virtual void zmien()=0;
};

Czy to dobry pomysł.

0 głosów
odpowiedź 23 grudnia 2015 przez criss Mędrzec (172,590 p.)
No jeżeli mają dostarczać związanych ze sobą funkcjonalności, to jak najbardziej. To ty musisz ocenić jak ci będzie łatwiej. Btw. funkcje wirtualne bez definicji (=0) nazywa się czysto wirtualnymi. Wirtualne mogą mieć definicje.

Podobne pytania

0 głosów
1 odpowiedź 292 wizyt
pytanie zadane 18 kwietnia 2016 w C# przez timrh Mądrala (6,030 p.)
0 głosów
2 odpowiedzi 289 wizyt
pytanie zadane 28 marca 2017 w C i C++ przez akiihombre Początkujący (250 p.)
+1 głos
1 odpowiedź 287 wizyt
pytanie zadane 3 lutego 2016 w C i C++ przez Ziuziek Mądrala (5,140 p.)

92,576 zapytań

141,426 odpowiedzi

319,651 komentarzy

61,961 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...