#include <memory>
#include <new>
#include <cstdlib>
#include <iostream>
template<typename T>
T*
allocate()
{
std::unique_ptr<T, void(*)(void*)> hold(static_cast<T*>(std::malloc(sizeof(T))),
std::free);
::new (hold.get()) T;
auto p = static_cast<T*>(hold.release());
std::cout << "allocating p:" << p << std::endl;
return p;
}
template<typename T>
void
deallocate(void* p)
{
std::cout << "freeing p:" << p << std::endl;
static_cast<T*>(p)->~T();
std::free(p);
}
#include <iostream>
struct Base
{
int i;
Base() {std::cout << "Base()\n";}
Base(const Base&) = delete;
Base& operator=(const Base&) = delete;
~Base() {std::cout << "~Base()\n";}
};
struct Derived
: public Base
{
int ii;
Derived() {std::cout << "Derived()\n";}
Derived(const Base&) = delete;
Derived& operator=(const Derived&) = delete;
virtual ~Derived() {std::cout << "~Derived()\n";}
void bark() const {std::cout << "Hi Derived!\n";}
};
int
main()
{
Derived *pd = new Derived();
std::cout << "pd:" << pd << std::endl;
Base *pb = pd;
std::cout << "pb:" << pb << std::endl;
void * pv = pb;
std::cout << "pv:" << pv << std::endl;
Derived *pd2 = static_cast<Derived*>(pv);
std::cout << "pd:" << pd2 << std::endl;
std::cout << "all at once:" << static_cast<Derived*>(static_cast<void*>(static_cast<Base*>(pd))) << std::endl;
std::unique_ptr<Derived, void(*)(void*)> p(allocate<Derived>(), deallocate<Derived>);
p->bark();
std::unique_ptr<Base, void(*)(void*)> p2 = std::move(p);
}