With a counter!
You set the counter to 1 when you first allocate the memory.
After that copy construction/assignment copies the counter along with the data and increments it.
The destructor is interesting.
You decrement your counter and if it reaches zero, you deallocate the data.