Вызов деструктора производного класса

Почему в этом коде был вызван деструктор класса Derived?

#include <iostream>

class Base
{
public:
Base() { std::cout << "Base::Base() \n"; }
~Base() { std::cout << "Base::~Base() \n"; }
};

class Derived : public Base
{
public:
Derived() { std::cout << "Derived::Derived() \n"; }
~Derived() { std::cout << "Derived::~Derived() \n"; }
};

Derived foo() { return Derived(); }

int main()
{
const Derived& instance = foo();
}

-1

Решение

Почему в этом коде был вызван деструктор класса Derived?

Поскольку Derived экземпляр создан в foo() выходит за рамки в конце основной программы.

#include <iostream>
using namespace std;

class Base {
public:
Base() {
std::cout << "Base::Base() \n";
}
~Base() {
std::cout << "Base::~Base() \n";
}
};

class Derived: public Base {
public:
int i;
Derived() {
i = 10;
std::cout << "Derived::Derived() \n";
}
~Derived() {
i = 0;
std::cout << "Derived::~Derived() \n";
}
int get() {
return i;
}
};

Derived foo() {
return Derived();
}

int main() {
const Derived& instance = foo();
cout << instance.i << endl;
return 0;
}

Вывод следующий:

Base::Base()
Derived::Derived()
10
Derived::~Derived()
Base::~Base()
3

Другие решения

Чтобы сделать его более интересным, рассмотрим модифицированный main:

const Base& instance = foo();

Этот код создает временный (объект, возвращаемый foo) типа Derived и продлевает время жизни объекта, связывая его с постоянной ссылкой типа Base, Срок действия временного объекта будет продлен до тех пор, пока ссылка не выйдет из области видимости, после чего объект будет уничтожен. Код примерно переведен на:

Derived __tmp = foo();
const Base& instance = __tmp;

В конце блока, содержащего ссылку instance, __tmp переменная также выходит из области видимости и удаляется. Обратите внимание, что даже без виртуального деструктора соответствующий деструктор называется __tmp имеет тип Derived (тип, возвращаемый функцией).

3