2012-06-18 4 views
8

Можно создать дубликат:
Why is the destructor not called for the returned object from the function?деструктор не вызывается при возврате локального экземпляра

Я написал код C++ (ниже), он был скомпилирован с GCC 4.6 и он побежал успешно. Но я не знаю, почему деструктор classA не вызывается при возврате с createA().

С ca является локальной переменной в createA() (т. Е. В стеке), я думаю, что его деструктор должен быть вызван при возврате из функции. Но на самом деле деструктор вызывается только один раз при возврате из функции main.

Кроме того, возврат локального экземпляра всегда отлично работает в этом тесте. Интересно, можно ли вернуть локальный экземпляр в стек стека, когда кадр был выскочен после возвращения.

Это мой код:

#include <iostream> 
#include <string.h> 

class classA 
{ 
public: 
    classA() { len = 0; v = 0; } 

    classA(int a) 
    { 
     len = a; 
     v = new int[a]; 
     for (int i = 0; i < a; i++) 
      v[i] = 2*i; 
    } 

    ~classA() 
    { 
     if (v) 
      { 
      memset(v, 0, len * sizeof(int)); 
      delete [] v; 
     } 
    } 

    int *v; 
    int len; 
}; 

classA createA(int a) 
{ 
    classA ca(a); 
    return ca; 
} 

using namespace std; 

int main() 
{ 
    int a = 10; 
    classA ca = createA(a); 
    classA *pca = &ca; 
    for (int i = 0; i < a; i++) 
     cout << pca->v[i]; 
    cout << endl; 
    return 0; 
} 

ответ

14

Это называется оптимизацией возвращаемого значение.

Короче говоря, компилятор не должен возвращать копию объекта для оптимизации кода.

Для са является локальной переменной, то есть в стеке [...]

Не обязательно. ca может быть создан непосредственно в вызывающем контексте, чтобы предотвратить дополнительную копию. Копирование elision - единственная оптимизация, которую может выполнять компилятор, который может изменить ожидаемое поведение.

+1

Он также относится к более общему имени: copy elision. –

+1

Собственно, это особый случай RVO, называемый * Named * Оптимизация возвращаемого значения. – dirkgently

+0

Спасибо Grigore. И у меня есть другой вопрос: безопасно ли возвращать переменную локального класса. Является ли этот метод, RVO, спецификацией C++ или просто трюком оптимизации компилятора? –