Первые два случая довольно явные злоупотребления временными. Основываясь на комментариях автора, они получили то, что пошло не так в create1
и create2
на данный момент, поэтому давайте сосредоточимся на create3
и почему это работает.
Спойлер: Это не так.
Я собираюсь взять несколько вольностей с кодом, чтобы сделать происходящее немного более очевидным. Во-первых, мы заменим vector
на простой класс, который позволит нам лучше видеть конструкцию и разрушение.
struct test
{
test()
{
std::cout << "test ctor\n";
}
~test()
{
std::cout << "test dtor\n";
}
};
Теперь мы делаем что-то похожее на Data
и используем test
вместо vector
struct Data {
Data(const test &data = {}) : data_(data)
{
std::cout << "data ctor\n";
}
~Data()
{
std::cout << "data dtor\n";
}
const test &data_;
void forceuse() // just to make sure the compiler doesn't get any bright ideas about
// optimizing Data out before we're through with it.
{
std::cout << "Using data\n";
}
};
И мы добавим немного дополнительной диагностики к create3
и снова заменим vector
на test
Data create3(const test &data = {}) {
std::cout << "in create3\n";
return Data(data); // good
}
и сделать то же самое с main
int main() {
{ // change the scope of data3 so that we can put a breakpoint at the end of main
// and watch all of the fun
std::cout << "calling create3\n";
auto data3 = create3(); // ok
std::cout << "returned from create3\n";
data3.forceuse();
}
}
Вывод этого
calling create3
test ctor
in create3
data ctor
test dtor
returned from create3
Using data
data dtor
test
создается во время вызова create3
и уничтожается при выходе из create3
. Это не живое в main
. Если он кажется живым в main
, это просто тупая неудача. Ваш друг и мое Неопределенное Поведение, будучи придурком. Опять же.
test
создается до Data
, но также уничтожается до Data
, оставляя Data
в плохом состоянии.
Вот приведенный выше код, все красиво собранные и запущенные в онлайн IDE: https://ideone.com/XY30XH