C ++: RAII и временные
Вы правы в том, что объекты в стеке уничтожаются, когда они выходят из области видимости.
Но вы игнорируете, что C ++ будет использовать временные объекты, необходимые. Вы должны узнать, когда компилятор создаст (и затем оптимизирует) временную переменную, чтобы ваш код работал.
Временные объекты
Обратите внимание, что ниже я описываю очень упрощенную «чистую» точку зрения на то, что происходит: компиляторы могут и будут выполнять оптимизацию, и среди них будут удалять бесполезные временные эффекты ... Но поведение остается тем же.
Целые
Давайте начнем медленно: что должно произойти, когда вы играете с целыми числами:
int a, b, c, d ;
// etc.
a = b + (c * d) ;
Код выше может быть записан как:
int a, b, c, d ;
// etc.
int cd = c * d ;
int bcd = b + cd ;
a = bcd ;
Параметры по значению
Когда вы вызываете функцию с параметром, передаваемым «по значению», компилятор делает ее временную копию (вызывая конструктор копирования).
И если вы вернетесь из функции «по значению», компилятор снова сделает ее временную копию.
Давайте представим объект типа T. Следующий код:
T foo(T t)
{
t *= 2 ;
return t ;
}
void bar()
{
T t0, t1 ;
// etc.
t1 = foor(t0) ;
}
можно записать в виде следующего встроенного кода:
void bar()
{
T t0, t1 ;
// etc.
T tempA(t1) // INSIDE FOO : foo(t0) ;
tempA += 2 ; // INSIDE FOO : t *= 2 ;
T tempB(tempA) // INSIDE FOO : return t ;
t1 = tempB ; // t1 = foo...
}
Таким образом, несмотря на то, что вы не пишете код, вызов или возврат из функции (потенциально) добавит много «невидимого кода», необходимого для передачи данных с одного уровня стека на следующий / предыдущий.
Опять же, вы должны помнить, что компилятор C ++ оптимизирует большинство временных процессов, поэтому то, что можно рассматривать как неэффективный процесс, - это всего лишь идея, и ничего больше.
О вашем коде
Ваш код утечет: вы «новый» объект и не удаляете его.
Несмотря на ваши опасения, правильный код должен быть больше похож на:
Point Point::operator+ (Point a)
{
Point c = Point(this->x+a.x,this->y+ a.y) ;
return c ;
}
Который со следующим кодом:
void bar()
{
Point x, y, z ;
// etc.
x = y + z ;
}
Создает следующий псевдокод:
void bar()
{
Point x, y, z ;
// etc.
Point tempA = z ; // INSIDE operator + : Point::operator+ (Point a)
Point c = z ; // INSIDE operator + : Point c = Point(this->x+a.x,this->y+ a.y) ;
Point tempB = c ; // INSIDE operator + : return c ;
x = tempB ; // x = y + z ;
}
О вашем коде, версия 2
Вы делаете слишком много временных. Конечно, компилятор, вероятно, удалит их, но тогда не нужно принимать небрежные привычки.
Вы должны как минимум написать код как:
inline Point Point::operator+ (const Point & a)
{
return Point(this->x+a.x,this->y+ a.y) ;
}