W wielu językach obiektowych występuje słowo kluczowe override
, którego dodawanie jest obowiązkowe podczas nadpisywania metod wirtualnych w klasach pochodnych (w przeciwnym wypadku generowanie jest ostrzeżenie). Jak można się spodziewać, C++ do takich języków nie należy :) A szkoda, bo wymóg stosowania override
zapobiega pomyłkom przy nadpisywaniu (np. literówkom w nazwach metod), które można wykryć dopiero w trakcie działania programu, gdy ze zdziwieniem odkrywamy, że zamiast nowej wersji metody wywoływana jest stara.
Można częściowo temu zaradzić, ale sposób jest brzydki. Polega on na stworzeniu makra zawierającego całą definicję klasy (albo przynajmniej deklaracje jej metod wirtualnych):
Następnie używamy go zarówno w definicji klasy bazowej, jak i pochodnych:
Dodatkowy parametr pozwala odróżnić obie sytuacje, co jest koniecznie w przypadku metod czysto wirtualnych (które nie posiadają implementacji).
Sztuczka jest być może pomysłowa, ale jednocześnie dość przygnębiająca. Dlaczego bowiem tak prosta sprawa jak zapobieganie pomyłkom przy nadpisywaniu metod wirtualnych musi być w C++ realizowana za pomocą brzydkich makr?…
Nie trzeba daleko szukac – wystarczy spojrzec na naglowki DirectX-a. Potrzeba matka wynalazkow.
“Dlaczego bowiem tak prosta sprawa jak zapobieganie pomyłkom przy nadpisywaniu metod wirtualnych musi być w C++ realizowana za pomocą brzydkich makr?…”
bo C++ “smierdzi”, zawsze tak bylo :< szkoda… Nowa wersja tez prawdopodobnie nie zmieni znaczaco stanu rzeczy.
Po prostu : C++ nie jest dla idiotów ;).
Zgadzam się z krajkiem. C++ pod kątem wrażliwość na typy i tak się znacząco różni od C, a ludziom ciągle mało :/
@I:
Wcale nie śmierdzi, jest po prostu skomplikowany, ale w zamian daje duużo możliwości. ;)
@krajek:
@RedHot:
What?! To może programujcie wszystko w asemblerze albo w kodzie binarnym… Strasznie głupim argumentem jest, że język jest trudny, bo używają go mądrzy ludzie. Każdy popełnia błędy, a nowoczesny język i jego kompilator powinny maksymalnie przed tymi błędami chronić. Żyjemy w czasach, w których liczy się szybkość dostarczania produktu. Trudny język nie przyspiesza czasu implementacji… :)
Sorki za błąd, miało być “Żyjemy w czasach, w których liczy się czas, w którym dostarcza się produkt. Trudny język nie skraca czasu implementacji… :)”
Nie do końca o to mi chodziło ;). Po pierwsze moją pierwszą wypowiedź należy traktować pół-żartem pół-serio. Część serio : to, że da się popełnić błąd, nie znaczy, że język jest zły. Ale od tego mamy głowę na karku, żeby problemów unikać np. przez ciągłe stosowanie tzw. dobrych praktyk pisania kodu . ;)
@krajek:
Rozumiem. Bardziej odniosłem się do Twojej i RedHot-a wypowiedzi jako do całości. Masz rację, od tego ma się głowę, żeby błędów nie popełniać. Z drugiej strony, można poddawać pod krytykę język, który na wiele błędów pozwala. No ale co tam, zobaczymy co przyniesie C++0x. ;)
@temat notki: I dlatego nie jestem zwolennikiem keywordowego minimalizmu, jaki IMO zastosowany jest w C++. Dlaczego nie ma w C++ tak banalnych do implementacji rzeczy jak wlasnie “override”, interfejsow, “sealed”, “abstract”, “finally”, “delegate”… I mozna by dlugo wymieniac rzeczy ktore wcale nie wymagaja poteznych zmian w architekturze jezyka, nie lamia zadnej kompatybilnosci z C, a znaczaco ulatwiliby prace. C++ nie pozjadal wszystkich rozumow zeby nie korzystac z pomyslow rodem z Javy czy C#… Pewnie ze C++ jest na tyle potezny ze wiekszosc z tych mechanizmow mozna sobie zrobic, ale “ladne” to nie jest… Po co sobie utrudniac skoro mozna prosciej ? Jezyk D ma takie same (albo nawet wieksze ) mozliwosci jak C++ dla programisty, a uproszczona skladnia i rozne “featursy” powoduja ze pisze sie prosciej. Nawet “pro” to powinien docenic… :)