zl3p
Предлагаю вам ознакомиться с таким понятием, как "конструктор копирования по умолчанию".
Код:

vector vector::operator + (const vector &obj)
{
if (this->n != obj.n) cout << "Error: diff. dim\n";
vector tmp(obj.n);
for (long i=0; i<obj.n; i++) {
tmp.x[i] = this->x[i] + obj.x[i];
}
return tmp; // (1)
}
void main()
{
{
vector a(3);
vector b(3);
a + b; // (2)
}
getch();
}
В строчке (1) происходят следующие действия: создаётся копия объекта tmp на стеке (используя конструктор копирования, который вы не объявили, но компилятор создал его самостоятельно), объект tmp был уничтожен (с вызовом деструктора, в первый раз). Затем в строке (2) временный объект используется (в данном случае никак не используется) и удаляется (второй вызов деструктора).
В общем решение простое - объявите конструктор копирования, например так
Код:

vector::vector (const vector &v)
{
n = v.n;
x = new real[n];
*this = v;
cout << "constructor \n";
}
Кстати, по стандарту создание временного объекта можно опускать. Поэтому один компилятор (gcc4) даже по вашему первоначальному коду генерирует корректную программу (т.к. не создаёт временный объект и тем самым опускает одну пару конструктор/деструктор), а другой (VS2005 в отладочной конфигурации) - нет.