Class allocators and deallocators are deprecated since with them, the user doesn't really know what is going on, leading to memory safety or leak issues. Typically, D programs assume new X
works with the garbage collector, and with the allocator being changed, it might not, leading to confusion.
Instead, if you want to change allocation, you should provide a factory function so it is clear that this is done differently. Together with private constructors, you can force the use of your custom function.
A reference is implemented as a pointer. When you write void foo(ref int b) { b = 10; }
in D, it is as if you wrote void foo(int* b) { *b = 10; }
in C. A pointer is a memory address represented as a number. It points to the object's location and allows changing the object through it. Copying pointers is as cheap as copying regular integers, so passing them to functions is pretty efficient.