You can do this without resorting to malloc/free or undefined behavior (I'm not sure about the reinterpret_cast, but at least construction/destruction can be done just fine).
To allocate the memory you can just call the global operator new directly. After that you use good old placement new to construct the object there. You have to guard the ctor-call though, since the "placement delete" function that's called if the ctor fails will not release any memory but just do nothing (just as placement new does nothing).
To destroy the object afterwards you can (and may) call the destructor directly, and to release the memory you can call the global operator delete.
I think it should also be OK to just delete it as you would any normal object, since calling the destructor and global operator delete afterwards is just what the normal delete will do, but I'm not 100% sure.
Your example modified like that:
#include <cstdlib>
#include <cstring>
#include <iostream>
class Hamburger {
int tastyness;
public:
char *GetMeat();
};
char *Hamburger::GetMeat() {
return reinterpret_cast<char *>(this) + sizeof(Hamburger);
}
int main(int argc, char* argv[])
{
Hamburger* hb;
// Allocate space for a Hamburger with 4 extra bytes to store a string.
void* space = operator new(sizeof(Hamburger) + 4);
// Construct the burger in that space
hb = new (space) Hamburger; // TODO: guard ctor call (release memory if ctor fails)
strcpy(hb->GetMeat(), "yum"); // OK to call member function on burger now
std::cout << "hamburger is " << hb->GetMeat() << std::endl;
// To delete we have to do 2 things
// 1) call the destructor
hb->~Hamburger();
// 2) deallocate the space
operator delete(hb);
}
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…