Мне было очень полезно понять, что конструктор копирования вызывается при назначении следующим образом:
class Base { };
class Derived : public Base { };
Derived x; /* Derived type object created */
Base y = x; /* Copy is made (using Base's copy constructor), so y really is of type Base. Copy can cause "slicing" btw. */
Так как y является фактическим объектом класса Base, а не оригинальным, функции, вызываемые это функции базы.