2011-07-12 18 views
17

W wielu sytuacjach pytanie nawet nie zadaje sobie pytania, ponieważ czasami dziedziczenie zapewnia niezbędne funkcje, których szablony nie mogą dostarczyć. Na przykład, kiedy potrzebuję adresować różne typy przez jeden typ podstawowy (polimorfizm), muszę użyć dziedziczenia.Kiedy należy używać szablonów zamiast dziedziczenia i na odwrót?

Istnieje jednak kilka przypadków, w których problem można rozwiązać zarówno w dziedziczeniu, jak i szablonach.

Weźmy na przykład strategii wzór podobny parametryzacji niektórych częściach kodu:

Jedno rozwiązanie pliku-parser może wyglądać następująco:

class FileParser 
{ 
    //... 
    public: 
     void Parse(ParsingAlgorithm* p); 
    //... 
} 

void FileParser::Parse(ParsingAlgorithm* p) 
{ 
    m_whatevertypeofvaluesineed = p->Parse(whateverparametersyouneed); 
} 

gdzie ParsingAlgorithm jest abstrakcyjną klasą bazową, która zapewnia pewne podstawowe metody i musi być dziedziczona przez każdego, kto lubi zaimplementować określony parser dla klasy FileParser.

Jednak samo można łatwo uzyskać stosując szablony:

template <class Parser> 
class FileParser 
{ 
    //... 
    public: 
     void Parse() 
     { 
      m_whatevertypeofvaluesineed = m_parser.Parse(whateverparametersyouneed); 
     } 

    private: 
     Parser m_parser; 
    //... 
} 

istnieją pewne ogólne zasady, które można użyć, aby zdecydować, czy używać szablonów lub dziedziczenia? Czy powinienem po prostu używać szablonów wszędzie tam, gdzie to możliwe, aby uniknąć nakładu czasu związanego z funkcjami wirtualnymi?

+0

Nieco duplikat [Czy CRTP całkowicie zastępuje funkcje wirtualne dla mniejszych projektów?] (Http://stackoverflow.com/questions/6613779/can-crtp-completely-replace-virtual-functionality-for-smaller-designs) – iammilind

Odpowiedz

17

Jeśli podczas kompilacji wiesz, jakie obiekty zamierzasz manipulować, wówczas statyczny polimorfizm z szablonami jest często najszybszym sposobem na zrobienie, i tworzy kod, który jest trochę bardziej zwięzły (bez potrzeby jawnego dziedziczenia) . Może być również bardziej ogólny, ponieważ nie jesteś ograniczony do silnej hierarchii klasowej.

Jeśli chcesz uzyskać polimorfizm w czasie wykonywania, nie masz wyboru i musisz używać wskaźników, dziedziczenia i niewielkiego obciążenia funkcji wirtualnych.

Moja własna opinia:

  • używać szablonów, jeśli to możliwe, to wygodne
  • Użyj dziedziczenia na czynniki kod (ale nie mają zbiory niejednorodną grupę), ale należy być ostrożnym z krojenia.
  • Nie martwić się o problemy z wydajnością połączeń wirtualnych
  • Czasem nie masz wyboru i chcesz hetergenous zbiory przeciąganie wokół bólu z zastosowaniem wskaźników
4

Szablony zapewnić kompilacji polimorfizm w przeciwieństwie do run-time polimorfizm dostarczonych przez dziedziczenie. Wolę używać szablonów, kiedy mogę.

Ten artykuł na temat Templates and Inheritance wyjaśnia szczegółowo.

-1

Moja sugestia, aby w tym przypadku nie używać ani używać oddzielnych funkcji dla każdego typu pliku;

Stream stream = open(filepath); 

    Image image = ParseBMP(stream); 
    // ...or 
    Image image = ParseJPG(stream); 

Nie trzeba robić rzeczy bardziej skomplikowanych niż są.

+0

Masz rację, ale mój przykład miał być tylko krótkim przykładem sytuacji, w której może powstać pytanie "dziedziczenie kontra szablony". – TravisG

+0

Nie zgadzam się. Używanie różnych funkcji jest sprzeczne z zasadą open-close. Http://en.wikipedia.org/wiki/Open/closed_principle –

+0

Nigdy wcześniej nie słyszałem o tym dyrektorze, ale wydaje mi się to złe. –

3

szablony są na ogół bardziej wydajnych w czasie wykonywania, ponieważ więcej praca jest wykonywana w czasie kompilacji.Z drugiej strony mogą być bardziej złożone, a zatem trudne do napisania i zrozumienia. Najlepiej z nich korzystać, gdy tylko możesz i, gdy nie komplikuje to całego rozwiązania.

Dla swoich przykładach, nie są one dokładnie funkcjonalnie równoważne: pierwszy wariant pozwala i wymaga utworzenia instancji parsera w czasie wykonywania, podczas gdy drugi wariant wymaga parser być wybrany przez programistę kiedy pisze kod.

Powiązane problemy