Код неверен и вызывает неопределенное поведение. Ваш класс Base
не имеет виртуального деструктора, что означает, что delete b
вызовет неопределенное поведение.
Причины UB при вызове delete
варьируются от факта, что он не будет освобождать производных ресурсов (что, похоже, является целью кода, ой!), До факта что он попытается освободить выделенную память, которая может работать или нет, в зависимости от расположения обоих объектов. Если ему не удастся освободить память, он, вероятно, потерпит крах, если ему удастся разместить новый вызов в следующей строке, он попытается инициализировать объект в памяти, который уже был освобожден ...
Даже если вы изменили код (пытаясь избежать проблем с освобождением) на:
Base* Base::create(int i) {
Derived *d = new Derived;
Base * b = static_cast<Base*>(d);
b->~Base(); // destruct, do not deallocate
new (b) Base(i);
return d;
}
Там, где delete
нет и, таким образом, этот конкретный источник неопределенного поведения пропал, код по-прежнему остается неопределенным поведением (вероятно, слишком многими способами, чтобы даже упоминать). Поскольку вызов деструктора по-прежнему является UB, даже если это не так, тот факт, что вы воссоздали тип Base
, означает, что динамическая диспетчеризация для этого объекта, вероятно, будет считать объект Base
, а не * 1018. * объект (в случае vtable
с vptr
, который указывает на информацию типа RunTime, будет ссылаться на Base
, а не Derived
)
И, вероятно, есть две или три другие вещи, которые могут пойти не так, и я не могу думать прямо сейчас ...