Ceci est une variante des questions Downcasting using the Static_cast in C++ et Safety of invalid downcast using static_cast (or reinterpret_cast) for inheritance without added memberssécurité de static_cast à pointer-à-classe dérivée de la base destructor
Je ne suis pas clair sur l'expression dans la norme « B qui est en fait un sous-objet d'un objet de type D, le pointeur résultant pointe vers l'objet englobant de type D "par rapport au comportement dans ~ B. Si vous lancez D dans ~ B, est-ce encore un sous-objet à ce moment-là? L'exemple simple suivant montre la question:
void f(B* b);
class B {
public:
B() {}
~B() { f(this); }
};
class D : public B { public: D() {} };
std::set<D*> ds;
void f(B* b) {
D* d = static_cast<D*>(b); // UB or subobject of type D?
ds.erase(d);
}
Je sais que le casting est une porte ouverte à la catastrophe, et de faire quelque chose comme ça du dtor est une mauvaise idée, mais une revendication collègue « Le code est valide et fonctionne correctement.Cette distribution est parfaitement valide.Le commentaire indique clairement qu'il ne devrait pas être déréférencé ". J'ai souligné que la distribution est inutile et nous devrions préférer la protection fournie par le système de type aux commentaires. Le plus triste, c'est qu'il est l'un des principaux développeurs/développeurs et un "expert" supposé C++. Puis-je lui dire que la distribution est UB?
Je pense que c'est UB, mais je ne suis pas sûr. Cependant, le code [au moins dans cet échantillon] absolu pisse pire que mes chaussettes après deux semaines dans un été chaud sans lavage ... La bonne chose ici serait d'avoir un descacheur dans 'D 'qui a enlevé l'objet de' ds' - cela ne devrait pas être fait dans 'B'. Cela évite bien sûr tout problème avec UB. Le fait que cela puisse effectivement fonctionner et être bien défini est hors de propos. Ou faites 'ds' dans un' std :: set bs' ... –
Tant qu'il n'y a pas d'autres classes dérivées de B et D n'a pas de membres supplémentaires, cela peut fonctionner. Mais le tout sent. Comment pouvez-vous vous assurer que chaque B est un D et si c'est sûr pourquoi auriez-vous des classes différentes en premier lieu? –
@MatsPetersson: Pourquoi pensez-vous que c'est UB? La norme en 5.2.9 donne un exemple presque égal aux OP, bien qu'il utilise des références: 'struct B {}; structure D: public B {}; D d; B & br = d; static_cast(br); 'Bien sûr, ce n'est qu'une question théorique. Le code dans la question de l'OP est horrible. –