Bonjour,
Je suis en train d'évaluer/analyser un outil d'analyse statique de code, dans sa dernière version, il y a une nouvelle vérification d'une règle MISRA C++ qui en substance exige que toute fonction virtuelle définie ne doive jamais être re-définie -- à quelques exceptions près pour les destructeurs et pour les fonctions virtuelles pures qui ont des implémentations par défaut.
Je gamberge depuis deux jours sur le sujet, et j'ai du mal à me faire une idée entre:
- ça n'apporte pas grand chose
- ça introduit des complications qui vont nous brider
- c'est un vrai gros plus.
Dans tous les cas, je n'ai pas trouvé d'exemples qui allaient vraiment dans un sens ou dans l'autre.
En gros, cela nous interdit les classiques
et ce n'est pas un mal. Bien au contraire -- oui, je préfère le DP Template Method.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7 struct Child : Super { virtual void f() { foo() Super::f(); bar(); } };
Mais cela complique aussi les choses pour définir des comportements par défaut qui pourraient être spécialisés dans des classes filles. Ce qui interdirait ce genre de chose (que j'utilise dans mes cours)
Est-ce vraiment hérétique d'être pragmatique en profitant de ce comportement par défaut ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 struct DataRenderer : noncopyable{ virtual ~DataRenderer() {} void render(DataList const& dataList_) { do_prologue(); for (auto const& data : dataList_) { do_render(data); } do_epilogue(); } private: virtual void do_prologue() {} // oui il y a une implémentation par défaut qui n'en fout pas une virtual void do_epilogue() {} // oui il y a une implémentation par défaut qui n'en fout pas une virtual void render(Data const& data_) = 0; } struct XMLDataRenderer : DataRenderer { private: virtual void do_prologue() override { cout << "<datalist>"; } // je viole la règle virtual void do_epilogue() override { cout << "</datalist>";} // je viole la règle virtual void render(Data const& data_) override { ... } }; struct GnuplotDataRenderer : DataRenderer { private: // ici, je profite de l'implémentation par défaut du prologue et de l'épiloque // et il en ira de même pour des sorties .csv/.tsv/... virtual void render(Data const& data_) override { ... } };
Partager