Un constructor de copia se usa para inicializar un objeto previamente no inicializado a partir de los datos de algún otro objeto.
A(const A& rhs) : data_(rhs.data_) {}
Por ejemplo:
A aa;
A a = aa; //copy constructor
Un operador de asignación se utiliza para reemplazar los datos de un objeto previamente inicializado con los datos de algún otro objeto.
A& operator=(const A& rhs) {data_ = rhs.data_; return *this;}
Por ejemplo:
A aa;
A a;
a = aa; // assignment operator
Podría reemplazar la construcción de la copia por la construcción predeterminada más la asignación, pero eso sería menos eficiente.
(Como nota al margen: Mis implementaciones anteriores son exactamente las que el compilador le otorga de forma gratuita, por lo que no tendría mucho sentido implementarlas manualmente. Si tiene una de estas dos, es probable que esté administrando manualmente algún recurso. En ese caso, según la regla de tres , es muy probable que también necesite el otro más un destructor).