The Nameless One,
p - это this->p для только что созданной копии, которую инициализируем с помощью obj
Копирующий конструктор, как и явствует из названия, создаёт один новый экземпляр, инициализируя его значениями из старого экземпляра (obj).
Копирующий конструктор вызывается, грубо говоря,
вместо конструктора по умолчанию. Точнее говоря, они просто равноправны. Неявное копирование при передаче объекта в функцию по значению, разумеется, будет выполняться конструированием новой копии с помощью копирующего конструктора.
Даже если ты явно не опишешь этот конструктор, компилятор сгенерирует реализацию по умолчанию - но она будет делать поверхностное копирование - на твоём примере хорошо видно, что переопределение копирующего конструктора нужно для того, чтобы избежать проблемы с копированием указателей вместо копирования данных.