c++ - Is a member function allowed to explicitly call its class destructor -


  • does following code have defined behavior ?
  • if not, part of code ub , section(s) of standard states ub ?
  • if code ub, there [minor] change can fix ?
  • if nothing can fix it, other code scheme/pattern used implement same feature ?

class c { public:     virtual ~c() {}     virtual void switch_me() = 0; };  class c1 : public c { public:     c1() : b(true)      { std::cout << "c1\n"; }     ~c1()               { std::cout << "~c1\n"; } private:     void switch_me();     bool b; };  class c2 : public c { public:     c2() : i(1)         { std::cout << "c2\n"; }     ~c2()               { std::cout << "~c2\n"; } private:     void switch_me();     int  i; }; 

void c1::switch_me() {     this->~c1();            // lifetime of *this ends here     std::cout << "blih\n";  // execute code                             // not attempt access object     new(this) c2();         // create c2 instance in-place }  void c2::switch_me() {     this->~c2();            // lifetime of *this ends here     std::cout << "blah\n";  // execute code...     new(this) c1();         // create c1 instance in-place } 

class cnt { public:     cnt()           { new(&storage) c1(); }     ~cnt()          { (*this)->~c(); }     c* operator->() { return reinterpret_cast<c*>(&storage); } private:     char storage[std::max(sizeof(c1),sizeof(c2))]; };  int main() {     cnt c;     c->switch_me();     c->switch_me();     return 0; } 

you not have undefined behavior regarding switch_me function: not access object in way after destruction, , next access happens on new object. might have ub if save pointer , reference c object returned vy operator-> , use after call switch_me per 3.8/7:

if, after lifetime of object has ended , before storage object occupied reused or released, new object created @ storage location original object occupied, pointer pointed original object, reference referred original object, or name of original object automatically refer new object and, once lifetime of new object has started, can used manipulate new object, if:

  • the storage new object overlays storage location original object occupied, ,
  • the new object of same type original object (ignoring top-level cv-qualifiers), ,
  • the type of original object not const-qualified, and, if class type, not contain non-static data member type const-qualified or reference type, ,
  • the original object derived object (1.8) of type t , new object derived object of type t (that is, not base class subobjects).

you have ub in other place, namely, storage. has weaker alignment object want place in it, , can cause alignment issues. use alignas keyword specify desired alignment:

alignas(c1) alignas(c2) char storage[std::max(sizeof(c1),sizeof(c2))]; 

if 2 alignment specifiers applied same declaration, larger used.


Comments

Popular posts from this blog

wordpress - (T_ENDFOREACH) php error -

Export Excel workseet into txt file using vba - (text and numbers with formulas) -

Using django-mptt to get only the categories that have items -