Присваивание объектов
Один объект можно присвоить другому, если оба объекта имеют одинаковый тип. По умолчанию, когда объект A присваивается объекту B, то осуществляется побитовое копирование всех элементов-данных A в соответствующие элементы-данные B. Если объекты имеют разные типов разные, то компилятор выдаст сообщение об ошибке. Важно понимать, одинаковыми должны быть имена типов, а не их физическое содержание. Например, следующие два типа несовместимы.
class ClassName1
{
 int a, b;
public:
 void set (int ia, int ib) {a=ia; b=ib;}
};
class ClassName2
{
 int a, b;
public:
 void set (int ia, int ib) {a=ia; b=ib;}
};
Так что попытка выполнить
ClassName1 c1;
ClassName2 c2;
c2 = c1;
окажется неудачной.
Важно понимать, что при присваивании происходит побитное копирование элементов данных, в том числе и массивов. Особенно внимательным нужно быть при присваивании объектов, в описании типа которых содержатся указатели. Например,
class Pair
{
 int a, *b;
public:
 void set (int ia, int ib) {a=ia; *b=ib;}
 int getb (){return *b;}
 int geta (){return a;}
};
main()
{
 Pair c1,c2;
 c1.set(10,11);
 c2 = c1;
 c1.set(100,111);
 cout << 'с2.b = '<< c2.getb();
}
В результате работы программы получим "c2.b = 111", а не 11, как ожидалось.
Чтобы избежать такого рода недоразумений, используют перегруженный оператор присваивания, в которой явным образом описается (т.е. контролируется) процесс присваивания элементов-данных одного объекта соответствующим элементам-данных другого объекта.
class Pair
{
 int a, *b;
public:
 Pair operator = (Pair p) 
 {
  a = p.a;
  *b = *(p.b);
  return *this;
 }
 ...
};
А вот как теперь будет выглядеть наш пример с трехмерным вектором.
class _3d 
{
 double x, y, z;
public:
 _3d ();
 _3d (double initX, double initY, double initZ);
 double mod () {return sqrt (x*x + y*y +z*z);}
double projection (_3d r) {return (x*r.x + y*r.y + z*r.z) / mod();}
_3d operator + (_3d b);
_3d operator = (_3d b);
};
_3d _3d::operator = (_3d b)
{
x = b.x;
y = b.y;
z = b.z;
return *this;
}
Наивно было бы предполагать, что для каждой новой переменной типа _3d создается копия функции, реализующей операторы "+" и "=". Каждая функция представлена в единственном экземпляре и в момент вызова получает один скрытый параметр - указатель на экземпляр переменной, для которого она вызвана. Этот указатель имеет имя this. Если используемая переменная не описана внутри функции, не является глобальной, то считается, что она является членом структуры и принадлежит рабочей переменной this. Поэтому при реализации функций операторов мы опускали путь доступа к полям структуры, для которой этот оператор будет вызываться.
В качестве аргументов функций-операторов выступают операнды, а возвращаемое значение - результат применения оператора. В частности для оператора "=" это необходимо, чтобы обеспечить возможность последовательного присваивания (a=b=c). Бинарные операторы имеют один аргумент - второй передается через указатель this. Унарные, соответственно, один - this.
