Предположения:
- оператор & не перегружен.
- Вывод в поток не определён для объекта .n_Name каким-то фантасмагорическим образом.
В определении функции указан способ передачи аргумента. Указано, что он передаётся по ссылке, но это техническая деталь, формально же при этом внутри функции с — это не адрес, а сам объект.
Если нужно передать адрес, то в описании должна быть *
constructor_and_d_and_c::constructor_and_d_and_c(const constructor_and_d_and_c* c)
В объекте может быть несколько полей данных. Адрес первого поля и объекта обычно совпадают.
& в теле функции означает взятие адреса. Код
cout << &c;
выдаст адрес объекта.
Код
cout << &c.n_Name;
выдаст адрес поля, и, возможно, он совпадёт с адресом c.
Судя по тому, что происходит. n_Name — это адрес памяти, которая выделяется для размещения строки. Не совсем понятно, зачем так сделано, можно было сделать полем класса строку напрямую, а не адрес на неё. Но так или иначе, у переменной содержащей адрес, тоже есть адрес.
Поэтому
cout << c.n_Name;
выдаёт какой-то адрес. Но это не адрес объекта с или поля c.n_Name. Это адрес динамически выделенной памяти под строку.
n_Name = new string(*(c.n_Name));
По адресу строки с помощью * получаем объект-строку, далее создаём новую строку, адрес пишем в n_Name.