#include <iostream>
using namespace std;
class base
{
public:
virtual ~base() { }
virtual void hi() = 0;
virtual size_t instance_size() = 0;
};
class A: base
{
public:
virtual ~A() override { printf("*A destroyed*\n"); }
virtual void hi() override { printf("Hi from A!\n"); }
virtual size_t instance_size() override { return sizeof(*this); }
};
class B: base
{
public:
string name;
B(const string& name): name(name) { }
virtual ~B() override { printf("*B destroyed*\n"); }
virtual void hi() override { printf("Hi from B, %s!\n", name.c_str()); }
virtual size_t instance_size() override { return sizeof(*this); }
};
class C: base
{
public:
virtual ~C() override { printf("*C destroyed*\n"); }
virtual void hi() override { printf("C says for you to go fuck yourself. >_<\n"); }
virtual size_t instance_size() override { return sizeof(*this); }
};
unsigned char raw_queue[999];
int main() {
unsigned char* push_ptr = raw_queue;
{
A* a_ptr = new (push_ptr) A;
printf("A (sizeof=%zd) created at offset %zd.\n", sizeof(A), push_ptr - raw_queue);
push_ptr += sizeof(A);
}
{
B* b_ptr = new (push_ptr) B("Rika");
printf("B (sizeof=%zd) created at offset %zd.\n", sizeof(B), push_ptr - raw_queue);
push_ptr += sizeof(B);
}
{
C* c_ptr = new (push_ptr) C;
printf("C (sizeof=%zd) created at offset %zd.\n", sizeof(C), push_ptr - raw_queue);
push_ptr += sizeof(C);
}
unsigned char* end_ptr = push_ptr;
for (unsigned char* pop_ptr = raw_queue; pop_ptr < end_ptr; )
{
base* obj = (base*)pop_ptr;
obj->hi();
size_t obj_size = obj->instance_size();
obj->~base();
pop_ptr += obj_size;
}
return 0;
}