slowko virtual, gdzie wedruje?

0

Ostatnio przegladaj rozne pliki zrodlowe zauwazylem niepokojaca mnie rzecz. Mianowicie czym rozni sie:

class base
{
public:
	virtual void pokaz()
	{
		cout << "obiekt klasy 'base'" << endl;
	}
};

class derived : public base
{
public:
	void pokaz()
	{
		cout << "obiekt klasy 'derived'" << endl;
	}
};

od tego gdyby przy dervied::pokaz() stalo by slowko virtual. Kiedys w pewnej ksiazce czytalem ze zasloniloby to mechanizm polimorfizmu. Teraz widze ze stosowane jest to w prawie kazdym kodzie.
Do tego mozna dodac ze w przykladowym kodzie w wikipedii w funkcji w klasie pochodnej stoi rowniez slowko virtual.

0

Z reguły zapisy są równoważne, bo kompilator brakujące virtual sobie doda. Ale nie wiem, czy wszystkie się tak zachowują. Zresztą, słowo virtual, to wskazówka również dla czytającego klasę, więc najlepiej je stawiać w deklaracji każdej klasy polimorficznej, a nie tylko bazowej.

dopisane:
dadanie virtual NIGDY nie zasłoni mechanizmu polimorfizmu! Gdzie byś go nie umieścił.

0

Jeżeli nie dodasz virtuala w derived to w klasie która dziedziczyłą by po derived nie mógłbyś przysłaniać tej metody.

0

Z tego co wiem wszystkie metody w klasach potomnych sa automatycznie wirtualne jeśli były w bazowej. Nie wiem o co kaman z przesłanianiem.

0

Z tego co wiem wszystkie metody w klasach potomnych sa automatycznie wirtualne jeśli były w bazowej.

exactly, jak napisałem wyżej: kompilator brakujące virtual sobie doda (jeśli było u rodzica).

Nie wiem o co kaman z przesłanianiem.

Ja też, bo poniższy kod działa tak samo zarówno teraz, jak i po dopisaniu virtuali. Więc klasom potomnym potomnych to również nie robi różnicy.

#include <iostream>
using namespace std;

class animal {
    public:      
        virtual void show() { cout << "animal" << endl; }
    };

class fish : public animal {
    public:  
        void show() { cout << "fish" << endl; }
    };

class sardine : public fish {
    public:
        void show() { cout << "sardine" << endl; }
    };

int main () {
    animal* ptr = new sardine();
    ptr->show();
    delete ptr;
    system("pause");
    }

Hmmm... może jakieś dziwactwa wynikają podczas przeładowywania funkcji wirtualnych, w dodatku z virtualem raz jest dopisywanym, a raz nie. Ale ja żadnych różnic w żadnym wypadku nie namierzyłem, a jeśli jakieś są (nie powinno! ale kompilatory czasem dziwnie się zachowują), to programista sam jest sobie winien - jedno słowo dopisać nietrudno, a zysk czytelności spory.

0

Po co są metody niewirtualne? Ja zawsze stosuję wirtualne. Nie wiem jak można zrobić jakiś porządny program(gdzie dużo klas dziedziczy po sobie) i używać funkcji niewirtualnych.

0

Niewirtualne są dla klas które po niczym nie dziedziczą i nikt po nich również nie dziedziczy. Zadeklarowanie metody jako wirtualnej powoduje pewne narzuty (niewielkie, ale zawsze ;)) które w takim wypadku były by zupełnie bezsensowne ;)

0

dzieki panowie za solidna odpowiedz.

0

@Ghostek
Eee, raczej nie jest to dobra definicja. Nic nie przszkadza, żeby dziedziczyć po klasie z nie-wirtualnymi metodami. Po prostu metody wirtualne są potrzebne do polimorfizmu.

@Faraday
Jeśli nie wiesz co to jest, to doczytaj sobie :)

0
DzieX napisał(a)

@Ghostek
Eee, raczej nie jest to dobra definicja. Nic nie przszkadza, żeby dziedziczyć po klasie z nie-wirtualnymi metodami. Po prostu metody wirtualne są potrzebne do polimorfizmu.

No ale dziedziczenie bez polimorfizmu jest tak jakby bezsensowne ;)

0

Czyżby?

0

No a do czego byś wtedy chciał to wykorzystać? Nie mam zielonego pojęcia do czego mogło by się przydać dziedziczenie bez polimorfizmu ;)

0

A Ty zmieniasz ciało każdej metody w klasie potomnej?

Dobra, poczytaj sobie jeszcze trochę na ten temat i sam dojdziesz do po prawnego wniosku. Mi sie nie chce tłumaczyć bo trochę tego jest. Z mojej strony EOT();

0

Wydaje mi sie ze virtual znakomicie nadaje sie do tworzenia interfejsow, no i oczywiscie virtualne destruktory przy polimorfizmie.

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