#include <iostream>
#include <cassert>
#include <utility> //For std::forward.
namespace Memory
{
template<typename Type, typename ...Args>
Type *Allocate(Args&& ...args)
{
//Allocate memory using 'malloc'.
Type *ptr = static_cast<Type*>(malloc(sizeof(Type)));
assert(ptr && "We're probably out of memory.");
//Manually call constructor, forwarding the arguments to the constructor.
new (ptr) Type(std::forward<Args>(args)...);
//Return the pointer.
return ptr;
}
template<typename Type>
void Deallocate(Type* &ptr) //Reference to a pointer. Huh, never had to use that before.
{
//Comment this assert out if you like the ability to pass null to 'delete'.
assert(ptr && "Trying to allocate an already NULL pointer.");
//Call the destructor manually.
ptr->~Type();
//Deallocate the memory.
free(ptr);
//Nullify the pointer (we got a reference to a pointer, so this is nulling the pointer that was passed into the function).
//Comment this line out if you want to do the nulling yourself.
ptr = nullptr;
}
} //End of namespace.
class MyClass
{
public:
MyClass(const std::string &str, int value)
{
std::cout << "MyClass(" << str << "," << value << ")" << std::endl;
}
~MyClass()
{
std::cout << "~MyClass()" << std::endl;
}
};
int main()
{
std::cout << "---------- Start ----------" << std::endl;
MyClass *myClass = Memory::Allocate<MyClass>("Hello", 357);
std::cout << "Pointer address: " << myClass << std::endl;
std::cout << "...program does stuff..." << std::endl;
Memory::Deallocate(myClass);
std::cout << "---------- End ----------" << std::endl;
std::cout << "Pointer address: " << myClass << std::endl;
return 0;
}