Java wyraźnie rozróżnia między class
i interface
. (Wierzę, że C # też, ale nie mam z tym doświadczenia). Jednak podczas pisania C ++ nie ma wymuszonego rozróżnienia między klasą a interfejsem.
W związku z tym zawsze postrzegałem interfejs jako obejście braku wielokrotnego dziedziczenia w Javie. Dokonanie takiego rozróżnienia jest w C ++ arbitralne i pozbawione znaczenia.
Zawsze stosowałem podejście „pisz rzeczy w najbardziej oczywisty sposób”, więc jeśli w C ++ mam coś, co można nazwać interfejsem w Javie, np .:
class Foo {
public:
virtual void doStuff() = 0;
~Foo() = 0;
};
i wtedy zdecydowałem, że większość implementatorów Foo
chciała udostępnić jakąś wspólną funkcjonalność, którą prawdopodobnie napisałbym:
class Foo {
public:
virtual void doStuff() = 0;
~Foo() {}
protected:
// If it needs this to do its thing:
int internalHelperThing(int);
// Or if it doesn't need the this pointer:
static int someOtherHelper(int);
};
Co sprawia, że nie jest to już interfejs w sensie Java.
Zamiast tego C ++ ma dwie ważne koncepcje związane z tym samym podstawowym problemem związanym z dziedziczeniem:
virtual
dziedziczenieKlasy bez zmiennych składowych nie mogą zajmować dodatkowego miejsca, gdy są używane jako baza
„Podobiekty klasy podstawowej mogą mieć rozmiar zerowy”
Spośród tych, których staram się unikać w miarę możliwości numer 1 - rzadko spotyka się scenariusz, w którym naprawdę jest to „najczystszy” projekt. # 2 jest jednak subtelną, ale ważną różnicą między moim rozumieniem terminu „interfejs” a funkcjami języka C ++. W rezultacie obecnie (prawie) nigdy nie nazywam rzeczy „interfejsami” w C ++ i mówię o klasach podstawowych i ich rozmiarach. Powiedziałbym, że w kontekście C ++ „interfejs” jest mylący.
Zwróciłem jednak uwagę, że niewiele osób dokonuje takiego rozróżnienia.
- Czy mogę coś stracić, dopuszczając (np.
protected
) Niefunkcjevirtual
w „interfejsie” w C ++? (Moje odczucie jest dokładnie odwrotne - bardziej naturalna lokalizacja dla wspólnego kodu) - Czy termin „interfejs” ma znaczenie w C ++ - czy oznacza tylko czysty,
virtual
czy też sprawiedliwe byłoby nazywanie klas C ++ bez zmiennych składowych nadal interfejsem?
~Foo() {}
w klasie abstrakcyjnej jest błędem w (prawie) każdych okolicznościach.
internalHelperThing
mogą być symulowane w prawie wszystkich przypadkach.