Различное поведение деструктора между vc9 и gcc - PullRequest
1 голос
/ 23 августа 2009

Следующий код дает другое количество деструкторов при компиляции в GCC и vc9. AFAIK при запуске на vc9 я получаю 5 деструкторов, которые я понимаю. Вызван оператор + перегружен, и два объекта создаются, когда возвращается временный объект. Это позволяет уничтожить 3 объекта. Когда вызывается перегруженный оператор =, создается один объект, а при возвращении снова временный. Это суммирует до пяти разрушений, не считая трех объектов, созданных в начале main.

Но когда я компилирую в GCC, я получаю 3.

Что заставляет меня догадаться, что при завершении и возврате функции временный объект не создается? или вопрос о различном поведении между компиляторами. Я просто не знаю, и некоторые разъяснения были бы хорошими.

#include <iostream>
using namespace std;

class planetCord {
    double x, y, z;
public:
    planetCord() { x = y = z = 0; }
    planetCord(double j, double i, double k) { x = j; y = i; z = k; }    
    ~planetCord() { cout << "destructing\n"; }
    planetCord operator+(planetCord obj);
    planetCord operator=(planetCord obj);
    void show();
};

planetCord planetCord::operator +(planetCord obj) {
    planetCord temp;
    temp.x = x + obj.x;
    temp.y = y + obj.y;
    temp.z = z + obj.z;
    return temp;
}

planetCord planetCord::operator =(planetCord obj) {
    x = obj.x;
    y = obj.y;
    z = obj.z;
    return *this;
}

void planetCord::show() {
    cout << "x cordinates: " << x << "\n";
    cout << "y cordinates: " << y << "\n";
    cout << "z cordinates: " << z << "\n\n";
}

int main() {
    planetCord jupiter(10, 20, 30);
    planetCord saturn(50, 100, 200);
    planetCord somewhereDark;

    jupiter.show();
    saturn.show();
    somewhereDark.show();
    somewhereDark = jupiter + saturn;  
    jupiter.show();
    saturn.show();
    somewhereDark.show();
    return 0;
}

Ответы [ 4 ]

3 голосов
/ 23 августа 2009

GCC реализует «оптимизацию возвращаемого значения» для пропуска временных. Установите VC9 в режим Release, и он, вероятно, сделает то же самое.

Если GCC действительно хорош, он видит, что temp внутри operator+ будет инициализирован по умолчанию, точно так же, как somewhereDark, и может просто использовать ссылку на somewhereDark напрямую, если попытается встроить функцию , Или он видит, что передача по значению бесполезна и вместо этого может передавать по ссылке.

2 голосов
/ 23 августа 2009

В вашем коде много не так. Могу ли я предложить вам изучить два понятия - consts и ссылки. Если ваш учебник по C ++ не охватывает их, приобретите новый учебник - я настоятельно рекомендую Ускоренный C ++ от Koenig & Moo.

2 голосов
/ 23 августа 2009

Допустимая, но не обязательная оптимизация для компилятора C ++ - включить жесткую последовательность:

ctor for new temporary object X
copy ctor from X to other object Y
dtor for X

, чтобы просто выполнить ctor непосредственно на Y. Действительно хороший оптимизатор C ++ может сделать это для функции clal (т.е. когда X - возвращаемое значение для функции). Похоже, GCC оптимизирует лучше. Меняется ли результат, когда вы играете с опциями оптимизации для двух компиляторов?

0 голосов
/ 23 августа 2009

На самом деле, в GCC, делаются временные. Это:

  • В операторе +.
  • Возвращено оператором +.
  • Возвращено оператором =.

В MSVC (я думаю, не могу проверить), также делаются временные. Тем не менее, некоторые не оптимизируются так, как GCC. Это:

  • Как параметр для оператора +.
  • В операторе +.
  • Возвращено оператором +.
  • как параметр для оператора =.
  • Возвращено оператором =.

Как ни странно, я думаю, что MSVC здесь прав, потому что я не уверен, стандартно ли поведение GCC.

Чтобы они оба вели себя одинаково, используйте ссылки const вместо передачи объекта по значению.

...