virtual vs szablon - różnice i podobieństwa

0

Hey, naszło mnie takie o to pytanie: kiedy jest sens używać szablonów a kiedy funkcji virtualnych? Czy ma to znaczenie?
Bo teoretycznie oba narzędzia mogą być wykorzystane w podobnych problemach.

Chodzi mi głównie o taki kontekst problemu: mam klasę bazową służącą do tworzenia na jej bazie klasy pochodnej.
Klasa pochodna musi posiadać utworzonych kilka funkcji, które będą wykorzystywane w innym obiekcie innej klasy.
I teraz pytanie: czy lepiej utworzyć funkcje virtualne w klasie bazowej, czy może lepiej utworzyć szablon klasy, która będzie wykorzystywać ten obiekt?

Ew. szablon zastosować w każdej klasie, która będzie wykorzystywać tą klasę.

Różnica w wydajności pewnie będzie niezbyt istotna dla szablonu (brak funkcji virtualnych) ale jednak interesuje mnie ten problem. Szczególnie, że funkcja pochodna o której mowa będzie wykorzystywana w dość długiej pętli!

Z góry dzięki za wasz udział w dyskusji ;-)

0

Nie do końca rozumiem. Umiesz podać konkretny przykład? Bo szablony nijak sie mają do polimorfizmu. Już prędzej odwieczna wojna delegacja vs. dziedziczenie ma tu chyba miejsce.

0
Shalom napisał(a):

Nie do końca rozumiem. Umiesz podać konkretny przykład? Bo szablony nijak sie mają do polimorfizmu. Już prędzej odwieczna wojna delegacja vs. dziedziczenie ma tu chyba miejsce.

Chodzi ogólnie o taki przykład jak poniżej.
Mamy dwie możliwości napisania klasy bazowej, pochodnej dla niej oraz obiektu, który będzie na nim pracował tj.:

class Ver1
	{
	public:
		virtual void fun() = 0;
		//inne zmienne, funkcje etc.
	};

class Der1 : public Ver1
	{
	public:
		void fun(){}
	};
class Ver2
	{
	public:
		//void fun(){} <- to nie jest w sumie potrzebne
		//inne zmienne, funkcje etc.
	};

class Der2 : public Ver2
	{
	public:
		void fun(){}
	};

class ForDer1
	{
	public:
		Ver1* ptr; //wskaźnik m.in. do obiektu dziedziczonego po ver1
		void fun()
			{
			ptr->fun();
			}
	};

template<class T>
class ForDer2
	{
	public:
		T* ptr;
		void fun()
			{
			ptr->fun();
			}
	};
0

Twoje pytanie sprowadza się do tego czy potrzebujesz mieć w programie generyczną klasę, która woła metody z innych klas, które z kolei mogą mieć wspólną klasę bazową albo nie. Innymi słowy jeśli masz 1 hierarchię dziedziczenia to nie piszesz template. Jeśli masz kilka ścieżek dziedziczenia albo nie masz w ogóle dziedziczenia ale z jakiś przyczyn metody z kilku klas mają taki sam interfejs (to powinny implementować interfejs...) to użyj szablonu.

0
satirev napisał(a):

Twoje pytanie sprowadza się do tego czy potrzebujesz mieć w programie generyczną klasę, która woła metody z innych klas, które z kolei mogą mieć wspólną klasę bazową albo nie. Innymi słowy jeśli masz 1 hierarchię dziedziczenia to nie piszesz template. Jeśli masz kilka ścieżek dziedziczenia albo nie masz w ogóle dziedziczenia ale z jakiś przyczyn metody z kilku klas mają taki sam interfejs (to powinny implementować interfejs...) to użyj szablonu.

Dzięki. Mam jednak pytanie uzupełniające dot. Twojej wypowiedzi.

  1. Czy jeśli dwie klasy dziedziczą po klasie bazowej to jest 1 hierarchiczne dziedziczenie czy nie? Bo mi poziomy hierarchii kojarzą się z czymś takim: pochodna po bazowej (pierwsza hierarchia) pochodna po pierwszej pochodnej (druga hierarchia) itd.
  2. Będzie tak, że po klasie bazowej będzie dziedziczyć tylko jedna klasa (klasa bazowa będzie częścią biblioteki) - czy w takim razie, gdy jest tylko jedno dziedziczenie po danej klasie ale jest wiele takich funkcji virtualnych np. 10 to czy to __jakieś __znaczenie?
0

Ilość metod wirtualnych jest dowolna jeśli dobrze zrozumiałem dobrze pytanie

0
scibi92 napisał(a):

Ilość metod wirtualnych jest dowolna jeśli dobrze zrozumiałem dobrze pytanie

Tego nikt nie kwestionuje.

0
Mały Lew napisał(a):
  1. Czy jeśli dwie klasy dziedziczą po klasie bazowej to jest 1 hierarchiczne dziedziczenie czy nie? Bo mi poziomy hierarchii kojarzą się z czymś takim: pochodna po bazowej (pierwsza hierarchia) pochodna po pierwszej pochodnej (druga hierarchia) itd.

Nie musi. Jeśli masz Animal, Cat i Dog to raczej Twoje wyobrażenie nie da sensownej hierarchii. Poza tym lepiej mieć płaską hierarchię niż łańcuch z 10 klasami, każda dziedzicząca po poprzedniej.

  1. Będzie tak, że po klasie bazowej będzie dziedziczyć tylko jedna klasa (klasa bazowa będzie częścią biblioteki) - czy w takim razie, gdy jest tylko jedno dziedziczenie po danej klasie ale jest wiele takich funkcji virtualnych np. 10 to czy to __jakieś __znaczenie?

Nie do końca rozumiem, ale zgadując: jak dziedziczysz to dziedziczysz wszystkie funkcje wirtualne.

0
Mały Lew napisał(a):
  1. Czy jeśli dwie klasy dziedziczą po klasie bazowej to jest 1 hierarchiczne dziedziczenie czy nie? Bo mi poziomy hierarchii kojarzą się z czymś takim: pochodna po bazowej (pierwsza hierarchia) pochodna po pierwszej pochodnej (druga hierarchia) itd.

Moim zdaniem lepiej rozważać łańcuchy dziedziczenia, bo lepiej to przemawia do wyobraźni. W Twoim przykładzie byłyby 2 łańcuchy dziedziczenia (2 kreski na diagramie poniżej):

Base
/     \

Foo Bar

Mały Lew napisał(a):
  1. Będzie tak, że po klasie bazowej będzie dziedziczyć tylko jedna klasa (klasa bazowa będzie częścią biblioteki) - czy w takim razie, gdy jest tylko jedno dziedziczenie po danej klasie ale jest wiele takich funkcji virtualnych np. 10 to czy to __jakieś __znaczenie?

Nie rozumiem pytania.

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