Mon style de codage comprend l'idiome suivant :
class Derived : public Base
{
public :
typedef Base super; // note that it could be hidden in
// protected/private section, instead
// Etc.
} ;
Cela me permet d'utiliser "super" comme alias de Base, par exemple, dans les constructeurs :
Derived(int i, int j)
: super(i), J(j)
{
}
Ou même en appelant la méthode depuis la classe de base dans sa version surchargée :
void Derived::foo()
{
super::foo() ;
// ... And then, do something else
}
Il peut même être enchaîné (je n'en ai pas encore trouvé l'utilité, cependant) :
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
}
Quoi qu'il en soit, je trouve l'utilisation de "typedef super" très utile, par exemple, lorsque Base est soit verbeux et/ou modélisé.
Le fait est que super est implémenté en Java, ainsi qu'en C# (où il est appelé "base", sauf erreur de ma part). Mais le C++ ne dispose pas de ce mot-clé.
Donc, mes questions :
- Cette utilisation de typedef est-elle super commune/rare/jamais vue dans le code avec lequel vous travaillez ?
- cette utilisation du typedef est-elle super Ok (c'est-à-dire que vous voyez des raisons fortes ou moins fortes de ne pas l'utiliser) ?
- est-ce que "super" est une bonne chose, est-ce qu'il devrait être quelque peu standardisé en C++, ou est-ce que cette utilisation à travers un typedef est déjà suffisante ?
Edita: Roddy a mentionné le fait que le typedef devrait être privé. Cela signifierait que toute classe dérivée ne pourrait pas l'utiliser sans le redéclarer. Mais je suppose que cela empêcherait aussi l'enchaînement super::super (mais qui va pleurer pour ça ?).
Edit 2 : Aujourd'hui, quelques mois après avoir utilisé massivement "super", je suis tout à fait d'accord avec le point de vue de Roddy : "super" devrait être privé. Je voudrais upvoter sa réponse deux fois, mais je suppose que je ne peux pas.
0 votes
Génial ! Exactement ce que je cherchais. Je ne pense pas avoir eu besoin d'utiliser cette technique jusqu'à présent. Excellente solution pour mon code multiplateforme.
7 votes
Pour moi
super
ressemble àJava
et il n'y a rien de mauvais, mais... MaisC++
prend en charge l'héritage multiple.2 votes
@user2623967 : Exact. Dans le cas d'un héritage simple, un "super" est suffisant. Maintenant, si vous avez un héritage multiple, avoir "superA", "superB", etc. est une bonne solution : Vous VOULEZ appeler la méthode à partir d'une implémentation ou d'une autre, donc vous devez DIRE quelle implémentation vous voulez. L'utilisation de typedef de type "super" vous permet de fournir un nom facilement accessible/inscriptible (au lieu, par exemple, d'écrire
MyFirstBase<MyString, MyStruct<MyData, MyValue>>
partout)0 votes
Notez que lorsque vous héritez d'un modèle, vous n'avez pas besoin d'inclure les arguments du modèle lorsque vous y faites référence. Par exemple :
template <class baz> struct Foo {...void bar() {...} ...}; struct Foo2: Foo<AnnoyinglyLongListOfArguments> { void bar2() { ... Foo::bar(); ...} };
Cela a fonctionné pour moi avec gcc 9.1 --std=c++1y (c++14).1 votes
...Hum, correction. Cela semble fonctionner dans n'importe quel standard c++, pas seulement le 14.