O ile rozumiem, wprowadzenie override
słowa kluczowego w C ++ 11 jest niczym innym jak tylko sprawdzeniem, czy zaimplementowana funkcja jest override
ing virtual
funkcji w klasie bazowej.
Czy to to?
O ile rozumiem, wprowadzenie override
słowa kluczowego w C ++ 11 jest niczym innym jak tylko sprawdzeniem, czy zaimplementowana funkcja jest override
ing virtual
funkcji w klasie bazowej.
Czy to to?
Odpowiedzi:
To rzeczywiście pomysł. Chodzi o to, że masz jasność co do tego, co masz na myśli, aby można było zdiagnozować cichy błąd:
struct Base
{
virtual int foo() const;
};
struct Derived : Base
{
virtual int foo() // whoops!
{
// ...
}
};
Powyższy kod się kompiluje, ale nie jest to, co mogłeś mieć na myśli (zwróć uwagę na brak const
). Jeśli powiesz zamiast tego, virtual int foo() override
otrzymasz błąd kompilatora, że twoja funkcja w rzeczywistości niczego nie przesłania.
override
funkcja „naprawia” to; musisz pamiętać, aby z niego korzystać, tak jak powinieneś pamiętać, aby napisać const
;)
explicit
definicje klas nie dotarły do C ++ 11. Huh
explicit
definicja klasy? Nigdy o tym nie słyszałem.
override
gdy ktoś zamierza to zrobić) jest bardziej prawdopodobne niż zapamiętywanie przypadków narożnych, tj. nie ma ogólności w kopiowaniu funkcji różnych prototypów, tylko nieprawidłowości, takie jak brak const
lub pisanie char
zamiast int
, itp.
override
w tej odpowiedzi wspomniano najlepszy przypadek użycia specyfikatora , który jest bardziej futurystyczny niż natychmiastowy. Odpowiedź sugeruje, że zachować override
się z virtual
metodą. W przyszłości, gdy ktoś omyłkowo zmieni podpis, zaczyna się jego przydatność.
Cytat z Wikipedii:
Zastąpienie specjalnego identyfikatora oznacza, że kompilator sprawdzi klasę (klasy) podstawową, aby sprawdzić, czy istnieje funkcja wirtualna z tą dokładną sygnaturą. A jeśli nie, kompilator wyłączy się.
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Edytuj (próbując nieco poprawić odpowiedź):
Zadeklarowanie metody jako „nadpisującej” oznacza, że ta metoda ma na celu przepisanie (wirtualnej) metody w klasie bazowej. Metoda zastępująca musi mieć tę samą sygnaturę (przynajmniej dla parametrów wejściowych), co metoda, którą zamierza przepisać.
Dlaczego to jest konieczne? Cóż, zapobiega się następującym dwóm typowym przypadkom błędów:
jeden błędnie wpisuje typ w nowej metodzie. Kompilator, nieświadomy, że zamierza napisać poprzednią metodę, po prostu dodaje ją do klasy jako nową metodę. Problem polega na tym, że stara metoda wciąż tam jest, nowa jest dodawana jako przeciążenie. W takim przypadku wszystkie wywołania starej metody będą działały tak jak poprzednio, bez żadnych zmian w zachowaniu (co byłoby celem samego przepisywania).
zapomina się zadeklarować metodę w nadklasie jako „wirtualną”, ale nadal próbuje się zapisać ją w podklasie. Chociaż zostanie to najwyraźniej zaakceptowane, zachowanie nie będzie dokładnie zgodne z zamierzeniami: metoda nie jest wirtualna, więc dostęp przez wskaźniki w kierunku nadklasy zakończy wywoływanie starej metody (nadklasy) zamiast nowej metody (podklasy).
Dodanie „przesłonięcia” wyraźnie to jednoznacznie ukazuje: przez to mówi się kompilatorowi, że trzy rzeczy się spodziewają:
Jeśli którykolwiek z nich jest fałszywy, sygnalizowany jest błąd.
* Uwaga: parametr wyjściowy jest czasem innego, ale pokrewnego typu. Przeczytaj o przemianach kowariantnych i przeciwwariantowych, jeśli jesteś zainteresowany.
Znalezione „ zastąpienie ” jest przydatne, gdy ktoś zaktualizował podpis metody wirtualnej klasy bazowej, taki jak dodanie opcjonalnego parametru, ale zapomniał zaktualizować podpis metody metody pochodnej. W takim przypadku metody między bazą a klasą pochodną nie są już relacjami polimorficznymi. Bez deklaracji zastąpienia trudno jest znaleźć tego rodzaju błąd.
override
jest to świetny sposób na wykrycie takich problemów, dobry zasięg testów jednostkowych powinien również pomóc.
Tak, tak jest. Jest to sprawdzenie, aby upewnić się, że nie spróbuje się przesłonić i nie zepsuć go przez nieudany podpis. Oto strona Wiki, która szczegółowo to wyjaśnia i zawiera krótki przykładowy przykład:
http://en.wikipedia.org/wiki/C%2B%2B11#Explicit_overrides_and_final
Wersja standardowa C ++ 17
Po przejrzeniu wszystkich override
trafień w standardowej wersji roboczej C ++ 17 N4659 , jedyne odniesienie, które mogę znaleźć do override
identyfikatora, to:
5 Jeśli funkcja wirtualna jest oznaczona zastąpieniem specyfikatora virt i nie zastępuje funkcji składowej klasy podstawowej, program jest źle sformułowany. [Przykład:
struct B { virtual void f(int); }; struct D : B { virtual void f(long) override; // error: wrong signature overriding B::f virtual void f(int) override; // OK }
- koniec przykładu]
więc myślę, że wysadzenie niewłaściwych programów to tak naprawdę jedyny efekt.