#include <new> struct Test { virtual void foo() { new ( this ) Test; } virtual void bar() { new ( this ) Test; foo(); } }; int main() { Test test; test.bar(); return 0; } 
  • What is this code? What elements of this code should be considered key in this question, and which - secondary? Triviality Test - Is this a key point or an accident? - AnT
  • I read your answers: they proved to me that the change of the object indicated by this before calling foo () inside bar () - UB - rikimaru2013
  • And, that is, it is about this moment? Offhand I will not say - we must look ... - AnT

3 answers 3

UB is unlikely (although let it be confirmed by the gurus in the standards), but now it’s easy to get into trouble like that. Imagine that Test asks for some kind of resource, say, memory.

 struct Test { Test() { cout << "Выделяем кучу памяти\n"; } ~Test() { cout << "Освобождаем кучу памяти\n"; } virtual void foo() { new ( this ) Test; } virtual void bar() { new ( this ) Test; foo(); } }; int main() { Test test; test.bar(); return 0; } 

See for yourself - http://ideone.com/kvspoc - what happens ...

    The standard is not prohibited , I create where I want.

    There is a possibility that the program will be able to

    But as already mentioned in the other answer and stated in the standard:

    The destructor has undefined behavior.

      As far as I understand, the problem indicated by @Harry can be circumvented as follows:

       struct A { A() { cout << "Alloc memory" << endl; } virtual ~A() { buzz(); } virtual void buzz() { cout << "Dealloc memory" << endl; } virtual void foo() { buzz(); new (this) A; } virtual void bar() { buzz(); new (this) A; foo(); } }; int main() { A test; test.bar(); return 0; } 

      And then everything will be fine

      • It can be even simpler :) - virtual void foo() { this->~A(); new (this) A; } virtual void foo() { this->~A(); new (this) A; } virtual void foo() { this->~A(); new (this) A; } , well, and accordingly bar() ... - Harry