Почему не вызывается деструктор при возвращении объекта из функции?
class myclass {
public:
int* ptr;
int get() { return *ptr; }
~myclass() {
free(ptr);
ptr = nullptr;
std::cout << "destruct" << std::endl;
};
myclass() {
std::cout << "default"<< std::endl;
ptr = (int*)malloc(sizeof(*ptr));
*ptr=999;
};
myclass(const myclass&) { std::cout << "copy" << std::endl; };
};
myclass func()
{
myclass a;
cout << "func: " << a.get() << endl;
cout << "func addr: " << a.ptr << endl;
return a;
}
int main()
{
myclass a= func();
cout << "main: " << a.get() << endl;
cout << "func addr: " << a.ptr << endl;
}
Вывод:
defolt
func: 999
func addr: 000001AF1E7CEF90
main: 999
func addr: 000001AF1E7CEF90
destruct
Хотел наглядно спроектировать неприятную ситуацию,когда из функции возвращаем стандартным конструктором копирования объект,после чего освобождается память и объект теперь ссылается на недействительную память,но в функции func() почему то не вызывается деструктор.Более того,почему то не вызывается даже конструктор копирования.Почему?
Ответы (1 шт):
Потому что тут
myclass a = func();
нет копирования. func сразу создает объект a в main (вечно путаю, как это правильно называется... copy elision, кажется... но начиная с какого-то С++ такое поведение обязательное).
Дополните код выводом адреса a:
myclass func()
{
myclass a;
cout << "a: " << &a << endl;
cout << "func: " << a.get() << endl;
cout << "func addr: " << a.ptr << endl;
return a;
}
int main()
{
myclass a= func();
cout << "a: " << &a << endl;
cout << "main: " << a.get() << endl;
cout << "func addr: " << a.ptr << endl;
}
У меня получается
a: 000000B74151FDD8
func: 999
func addr: 000002B2AB5AD830
a: 000000B74151FDD8
main: 999
func addr: 000002B2AB5AD830
так что, как видите, a оlин и тот же и в func, и в main.
Update
Ага, таки немного соврал. Это вроде бы NRVO, и является не обязательной оптимизацией, в отличие от RVO. Смотрите тут - https://en.cppreference.com/w/cpp/language/copy_elision