Mój styl kodowania obejmuje następujący idiom:
class Derived : public Base
{
public :
typedef Base super; // note that it could be hidden in
// protected/private section, instead
// Etc.
} ;
To pozwala mi używać „super” jako aliasu dla Base, na przykład w konstruktorach:
Derived(int i, int j)
: super(i), J(j)
{
}
Lub nawet podczas wywoływania metody z klasy podstawowej w jej przesłoniętej wersji:
void Derived::foo()
{
super::foo() ;
// ... And then, do something else
}
Można go nawet połączyć w łańcuch (wciąż muszę to do tego wykorzystać):
class DerivedDerived : public Derived
{
public :
typedef Derived super; // note that it could be hidden in
// protected/private section, instead
// Etc.
} ;
void DerivedDerived::bar()
{
super::bar() ; // will call Derived::bar
super::super::bar ; // will call Base::bar
// ... And then, do something else
}
W każdym razie uważam, że użycie „typedef super” jest bardzo przydatne, na przykład, gdy Base jest albo gadatliwa i / lub szablonowa.
Faktem jest, że super jest zaimplementowane w Javie, a także w języku C # (gdzie nazywa się to „base”, chyba że się mylę). Ale C ++ nie ma tego słowa kluczowego.
Więc moje pytania:
- czy takie użycie typedef jest bardzo powszechne / rzadkie / nigdy nie widywane w kodzie, z którym pracujesz?
- czy to użycie typedef super Ok (tzn. czy widzisz mocne, czy nie tak mocne powody, aby go nie używać)?
- czy „super” powinno być dobrą rzeczą, czy powinno być nieco wystandaryzowane w C ++, czy też to użycie przez typedef już wystarcza?
Edycja: Roddy wspomniał, że typedef powinien być prywatny. Oznaczałoby to, że żadna klasa pochodna nie byłaby w stanie jej użyć bez ponownego jej opublikowania. Ale sądzę, że zapobiegnie to również super :: super łańcuchowi (ale kto będzie za to płakać?).
Edycja 2: Teraz, kilka miesięcy po masowym użyciu „super”, całym sercem zgadzam się z poglądem Roddy'ego: „super” powinien być prywatny. Chciałbym dwukrotnie głosować za jego odpowiedzią, ale chyba nie mogę.
super
wygląda Java
i nie jest niczym złym, ale ... Ale C++
obsługuje wielokrotne dziedziczenie.
MyFirstBase<MyString, MyStruct<MyData, MyValue>>
template <class baz> struct Foo {...void bar() {...} ...}; struct Foo2: Foo<AnnoyinglyLongListOfArguments> { void bar2() { ... Foo::bar(); ...} };
działało to dla mnie z gcc 9.1 --std = c ++ 1y (c ++ 14).