Today: ------ new and delete ------------ The following code calls the new operator: string *ps = new string("memory management"); This does two things, and always two things: 1.) allocates enough memory for the object AND 2.) calls the non-default constructor We can, however, overload how the memory is allocated. The new operator calls a function to do the allocation, which itself can be overloaded with a user-defined function. This function is called operator new (yeah, I know it is confusing) void * operator new(size_t size); In general this does not initialize the memory (think malloc) but you could if you were absolutely desperate. You can overload operator new to have multiple parameters, but size_t size must always be the first one. You may never want to call operator new directly, but you can like this: void * rawMem = operator new(sizeof(string)); Although rawMem has all of the space to store a string, we need to run the constructor to initialize it. And we can't... so in a way we are stuck. Compilers can call constructors, however, and that is why we use the new operator to initialize objects whenever we want dynamic memory management. More simply, it is the job of the new we have used before to take the raw memory and turn it into a brand new, shiny object we can use. There is an exception, however: placement new. Consider the code similar to the one in the handout: class Foo { public: Foo(int BarSize); .... Foo * constructFooInBuffer(void* buffer, int BarSize) { return new (buffer) Foo (barSize); } The additional argument buffer will be given to operator new, so we need the following overloaded function as well: void * operator new(size_t, void *location) { return location; } Because size_t is a placeholder, we don't have to always specify it. It will compile as listed above (despite the doubts you may have). We do need, however, to #include to use the placement new functionality. Just like with new, there is also an operator delete we can utilize if needed. It is structured like follows: void operator delete (void * memtobedealloc); whenever "delete str" is called for a string, it generates two lines of code: str->~string(); operator delete(str); It follows that operator new and operator delete can be used sort of like malloc and dealloc in C++, if needed. Note, though, that you can not run delete directly on something created using operator new. It is possible as shown in the handout to do something like: pw ->~Widget(); freeShared(pw); What about arrays? There is also an operator called new[] that does dynamic allocation. This also can be overloaded. Cool, right?