Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

Funkcje wirtualne - ale po co mi to?

Ostatnio zmodyfikowano 2017-01-29 12:50
Autor Wiadomość
jankowalski25
» 2017-01-28 19:45:12
To tylko po to stworzono virtual?
Zazwyczaj prościej wstawić
virtual
, niż ręcznie obsługiwać
VTABLE
 i
VPTR
. Można napisać kod korzystający z polimorfizmu bez słowa kluczowego
virtual
.

Na przykład ja w ogóle nie korzystam z funkcji wirtualnych, bo nie używam klas i dziedziczenia. Jak już to wskaźniki do funkcji.
To nie wyklucza korzystania z polimorfizmu. W pewnym uproszczeniu
VTABLE
 to właśnie tablica wskaźników do funkcji.
P-157072
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-01-28 21:03:09
Ok, mniej więcej rozumiem, zamknę temat, tylko jeszcze jedna sprawa.
@Mateczek
Z której klasy dziedziczy metoda painEvent? Bo Twoja klasa dziedziczy z klasy QWidget, więc logiczne jest, że musi być to metoda właśnie tej klasy.
Ale zastanawia mnie coś jeszcze; Skoro tworzysz wskaźnik ResizeLabel to funkcja nie musiałaby być virtual. Musiałaby być virtual, gdybyś tworzył wskaźnik do obiektów klasy z której dziedziczymy, np.
C/C++
class QWidget
{
public:
    void paintEvent();
};

class ResizeLabel
    : public QWidget
{
public:
    void paintEvent(); // tu jest deklaracja paintEvent, wiadomo, dalej zmieniasz jej cialo
}

//I teraz;

//Jeśli stworzysz wskaźnik
ResizeLabel * mlabel;
//i dynamicznie stworzysz obiekt
mlabel = new ResizeLabel;

//To przy wywołaniu funkcji w ten sposób
mlabel->show();
//To zawsze wywola sie show() klasy ResizeLabel, bo wskaźnik miał typ tejże klasy. Więc wirtualka jest tu nie potrzebna. Gdyby było tak:
QWidget * mlabel = new ResizeLabel;
mlabel->show(); // to teraz bylaby potrzebna funkcja z virtual, by wywolala sie metoda dla klasy ResizeLabel, a nie QWidget

PS. co właściwie robi funkcja show? Bo nigdzie nie wywoływałeś paintEvent() a jednak narysowało prostokąt?
Z góry dzięki za odp :)
P-157074
mateczek
» 2017-01-28 21:14:08
to jest metoda virtualna klasy QWidget.
http://doc.qt.io/qt-4.8/qwidget.html

Ja pisałem nowy widget, który dziedziczył po klasie bibliotecznej. A ponieważ jest to metoda virtualna więc zamiast domyślnej wywołała się moja i narysowała prostokąt. Na tym to polega 



Qwidget->paintevent()
 jest wywoływane z automatu, kiedy przemieszczasz okno rozszerzasz okno itp. Nie ma to nic wspólnego z metodą show().   A dzięki "virtual" zamiast QWidget->paintEvent() wywołuje się paintEvent() mojej labelki.


//To zawsze wywola sie show() klasy ResizeLabel
to i tak jest metoda klasy bazowej. Ja w swojej klasie "resizelabel" jej nie implementowałem. Zwykłe dziedziczenie
P-157076
karambaHZP
» 2017-01-28 21:39:31
P-157078
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-01-28 23:15:31
@mateczek
Już rozumiem, masz wskaźnik na obiekt swojej klasy (resizeLabel) i wywołujesz na jego rzecz funkcję show() (wspólną dla obu klas), ale w tej funkcji wywołuje się funkcja paintEvent() która jest już Twoja, prawda?

Ale jeszcze dwa, zupełnie odrębne pytania;
- do czego służy obiekt klasy QPainter (taki jak tworzysz w 4:40 )
- Co to za klasa QPaintEvent? Użyłeś wskaźnika typu tej klasy. Jest on argumentem w PaintEvent i do czego służy, skoro (jak podpowiedział Ci program w 7:00) nie użyłeś go ani razu?
P-157084
mateczek
» 2017-01-29 12:07:39
http://doc.qt.io/qt-4.8/qwidget.html#paintEvent

taka jest deklaracja metody w klasie qWidget. Tak więc re-implementacja metody wirtualnej musi mieć taką samą postać. I nie mam pojęcia do czego służy ten parametr. Wiem tylko że gdybym go nie podał to kompilator nie uznał by mojej metody jako re implementacji metody wirtualnej, Była by to zwyczajna metoda klasy (i zwyczajnie nic by mi nie rysowało)

Ja Robiłem tablice wyświetlającą na TV liczniki elementów (wizualizacja sterowników PLC) i na bazie tego mini projektu powstał ten tutorial o malowaniu na widgecie.

metoda show() jest przeciwieństwem metody hide() (ukrywa lub pokazuje widgety). A metoda virtualna
void QWidget::paintEvent( QPaintEvent * event )
 wywołuje się zawsze gdy trzeba przerysować widget (zmiana rozmiaru przesunięcie okna itp)
P-157090
latajacaryba
Temat założony przez niniejszego użytkownika
» 2017-01-29 12:50:59
To wszystko. Wielkie dzięki. :)
Temat zamykam
P-157092
1 « 2 »
Poprzednia strona Strona 2 z 2