2013-02-25 11 views
7

Jestem teraz nauki C++ bok OO, i mam to cały czas:C++ różnica między virtual = 0; i funkcja pusta

class SomeClass{ 
    virtual void aMethod()=0; 
} 

class AnotherClass{ 
    void anotherMethod(){/*Empty*/} 
} 

class SomeClassSon : public SomeClass{ 
    void aMethod(){/*Also Empty*/} 
} 

Moje wątpliwości to: jaka jest różnica między tymi metodami 3. Wirtualny jest równy zero, pusty i wirtualny, ponieważ jest dziedziczony, pusty.

Dlaczego nie mogę po prostu zrobić metodę SomeClassSon jak ojciec (virtual void równa zero?)

+0

'SomeClass s; s.aMethod() 'nie jest prawidłowym połączeniem. – andre

+3

Różnica polega na tym, że przy "= 0" w klasie bazowej każda klasa pochodna * musi * implementować metodę. –

+2

@DavidSchwartz - musi zaimplementować funkcję *, jeśli klasa jest instancjonowana *. Jeśli funkcja nie jest zaimplementowana, klasa jest abstrakcyjna. –

Odpowiedz

10

Dla

class SomeClass{ 
    virtual void aMethod()=0; 
} 

obecności czystej metody wirtualnej sprawia, że ​​klasa streszczenie. Gdy masz już jedną taką czystą metodę wirtualną, =0, w klasie nie możesz utworzyć instancji klasy. Co więcej, każda klasa pochodna musi implementować czystą wirtualną aMethod(), lub też staje się klasą abstrakcyjną.

W swojej klasie pochodnej nadpisujesz czystą wirtualną metodę z góry, co powoduje, że klasa pochodna nie jest abstrakcyjna. Możesz utworzyć instancję tej klasy pochodnej.

Ale w klasie pochodnej ciało metody jest puste, prawda? Dlatego twoje pytanie ma sens: dlaczego nie uczynić klasy czystym wirtualnym. Twoja klasa może pociągać za sobą inne metody. Jeśli tak, nie można utworzyć instancji SomeClass (jest to metoda czysto wirtualna), podczas gdy klasa podrzędna SomeClassSon może być.

To samo dotyczy Twojego AnotherClass, który można utworzyć instancją, w przeciwieństwie do SomeClass.

6

Różnica polega na tym, że virtual void aMethod() = 0 jest pure virtual function, co oznacza, że:?

  1. SomeClass staje się abstrakcyjna klasa bazowa, , co oznacza, że ​​nie można utworzyć instancji.
  2. Każda klasa, która dziedziczy z SomeClass musi wdrożyć aMethod, albo też staje się abstrakcyjna klasa bazowa, która nie może być instancja

Należy pamiętać, że każda klasa z jednym lub więcej czystych funkcji wirtualnych jest automatycznie abstrakcyjną klasą bazową.

+1

Może chodziło Ci o właściwą rzecz, ale powiedziałeś źle: klasy wywodzące się z 'SomeClass' są * nie * zmuszone do implementacji funkcji, ale jeśli nie, to również są abstrakcyjne. –

1

Czysta virtual powoduje, że klasa jest abstrakcyjna. Pusta metoda inna niż wirtualna nic nie robi - po prostu prowadzi do błędu linkera, jeśli spróbujesz go wywołać. Natomiast nie można próbować wywoływać czystego virtual (chyba że spróbujesz wywołać go z konstruktora, który i tak jest zły), ponieważ kompilator nie pozwoli ci utworzyć tego obiektu.

Istnieje również logiczna różnica - metoda oznaczona virtual będzie wirtualna w łańcuchu dziedziczenia - pozostałe to zwykłe metody.

1

Funkcja czysto wirtualna (Twój pierwszy przykład, z =0) oznacza, że ​​funkcja musi zostać nadpisana w klasie pochodnej, aby obiekt tej klasy był instancjonowany.

Drugi to po prostu funkcja członkowska, która nie robi nic. Ponieważ funkcja ma inną nazwę, a klasa nie jest związana z SomeClass, te dwa nie wpływają na siebie nawzajem.

Trzeci zastępuje funkcję czystej wirtualnej, więc możliwe jest utworzenie instancji SomeClassSon, ale w klasie pochodnej funkcja zastępowana nic nie robi.

2

deklaracja aMethod() = 0 mówi kompilatorowi, że ta metoda musi być przewidziana w podklasach. Żadnej podklasy, która nie implementuje metody, nie można utworzyć w instancji. Pomaga to zapewnić, że wszystkie obiekty klasy bazowej będą miały zaimplementowaną metodę.

3

"Równa się 0", o której mówisz, nazywa się "czysta wirtualna". Jest to funkcja, którą dziecko, które chce być utworzone, ma zaimplementować w przeciwieństwie do zapewnienia podstawowej funkcjonalności, co oznacza, że ​​klasa nadrzędna ma zdefiniować funkcjonalność, która musi istnieć, ale rodzic nie ma wiedzy o tym, jak dziecko to zrobi. Zauważ, że powoduje to, że klasa jest abstrakcyjna, ponieważ nie można jej utworzyć. Na przykład mogę chcieć zdefiniować klasę "Ssak", z której mogę dziedziczyć i chcę, aby jej dzieci działały w określony sposób - ale nie mogę po prostu stworzyć "Ssaka". Zamiast tego utworzę klasę "Żyrafa" i upewnię się, że działa tak, jak powinna.

Zostało to również wyjaśnione w pytaniu o numer SO.

Funkcja "Empty", o której mówisz, to funkcja, w której funkcja jest zdefiniowana i może zostać wywołana - ale nic nie robi.

Powiązane problemy