Jestem początkujący w C++. Napotkałem słowo kluczowe override
użyte w pliku nagłówkowym, nad którym pracuję. Czy mogę wiedzieć, jakie jest rzeczywiste użycie override
, być może na przykładzie będzie to łatwe do zrozumienia.Do czego służy słowo kluczowe "zastąp" w C++?
Odpowiedz
override
kluczowe służy dwóm celom: „Jest to sposób wirtualnego, to jest przesłanianie wirtualnego metodę klasy bazowej”
- pokazuje czytnikiem kodu
- Kompilator wie również, że jest to przesłonięcie, więc może "sprawdzić", że nie zmieniasz/dodawanie nowych metod, które uważasz, że są przesłonięte.
Aby wyjaśnić ten ostatni:
class base
{
public:
virtual int foo(float x) = 0;
};
class derived: public base
{
public:
int foo(float x) override { ... do stuff with x and such ... }
}
class derived2: public base
{
public:
int foo(int x) override { ... }
};
W derived2
kompilator wyda błąd dla "zmieniając typ". Bez override
, co najwyżej kompilator dałby ostrzeżenie "ukrywasz wirtualną metodę o tej samej nazwie".
nie powinien nagłówek funkcji dla * foo * być podobny w klasie * deriv2 * ?? Skompilowałem to za pomocą VS2017 i otrzymałem błąd kompilacji. Mam na myśli to, że w * deriv2 * * nagłówek foo * musi być: * int foo (float x) override {...} * –
Uhm, to w całości kwestia, przykład kodu pokazuje, jak można użyć override do wykrycia błędu! –
Myślę, że # 3 jest to, że zastąpienie może być używane do wykrywania funkcji, która ma zostać zastąpiona (należąca do klasy/interfejsu nadrzędnego) jest usuwana (niezmienna). Jest to użyteczne, jeśli podklasa oczekuje wywołania zwrotnego, ale nigdy nie stanie się tak ze względu na zmianę biblioteki, itp. – Hei
override
to słowo kluczowe C++ 11, które oznacza, że metoda jest "przesłonięciem" metody z klasy bazowej. Rozważmy następujący przykład:
class Foo
{
public:
virtual void func1();
}
class Bar : public Foo
{
public:
void func1() override;
}
Jeśli B :: func1() podpis nie jest równa A :: func1() podpis błąd kompilacji zostanie wygenerowany ponieważ B :: func1() nie nadpisać :: func1(), zamiast tego zdefiniuje nową metodę o nazwie func1().
Zgodnie ze specyfikacją C++, "przesłonięcie" jest "identyfikatorem o specjalnym znaczeniu". Ale takie rzeczy w języku C# są nazywane słowami kontekstowymi. –
Wikipedia mówi:
Metoda nadrzędnym, programowania obiektowego, to funkcja języka, który pozwala podklasą lub dziecko klasa zapewnienie konkretnej realizacji metody, które zostały podane przez jednego z jego nadrzędnych lub klasy nadrzędne.
W szczególności, gdy masz foo obiektu, który ma pustkę Hello() Funkcja:
class foo {
virtual void hello(); // Code : printf("Hello!");
}
dzieckiem foo, będzie mieć również Hello() Funkcja:
class bar : foo {
// no functions in here but yet, you can call
// bar.hello()
}
Możesz jednak wydrukować "Hello Bar!" gdy funkcja hello() jest wywoływana z obiektu paska. Można to zrobić za pomocą nadpisanie
class bar : foo {
virtual void hello() override; // Code : printf("Hello Bar!");
}
Nie potrzebujesz identyfikatora nadpisania, aby zrobić to w C++, to po prostu wymusza, że robisz to poprawnie. – Goose
i jako dodatku do wszystkich reaguje, FYI: override
nie jest słowem kluczowym, ale specjalny rodzaj identyfikatora! Ma znaczenie tylko w kontekście deklarowania/definiowania funkcji wirtualnych, w innych kontekstach jest to po prostu porządkowy numer identyfikator. Aby uzyskać szczegółowe informacje, przeczytaj 2.11.2 z Standard.
// kate: hl C++11;
#include <iostream>
struct base
{
virtual void foo() = 0;
};
struct derived : base
{
virtual void foo() override
{
std::cout << __PRETTY_FUNCTION__ << std::endl;
}
};
int main()
{
base* override = new derived();
override->foo();
return 0;
}
wyjściowa:
[email protected] /work/tests $ g++ -std=c++11 -o override-test override-test.cc
[email protected] /work/tests $ ./override-test
virtual void derived::foo()
Działa (tu i na końcu), ponieważ nie można używać zwykłych identyfikatorów, w których umieszczane są te słowa kluczowe kontekstowe. – CTMacUser
dlaczego do diabła nie jest zabronione? –
@FerencDajka 1. Dlaczego to powinno być? 2. Nagłe dodanie nowego słowa kluczowego (tj. Zabraniające używania go wszędzie indziej) złamałoby kompatybilność wsteczną. – idmean
Należy również zauważyć, C++ 11 wprowadził 'final' słowa kluczowego. –
@JesseDobry i jeszcze raz: 'final' __also nie jest słowem kluczowym__ !!! – zaufi
@zaufi: Tak, nauczyłem się czegoś nowego. I + 1ed twoją odpowiedź. –