Это прежде всего ошибка компиляции, а не обязательный сбой при запуске: неявный деструктор Example использует default_delete для неполного Impl. Определите деструктор там, где Impl уже известен.
Коррекция программы с применением unique_ptr
Это прежде всего ошибка компиляции, а не обязательный сбой при запуске: неявный деструктор Example использует default_delete для неполного Impl. Определите деструктор там, где Impl уже известен.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Имеется небольшое приложение, разбитое на три исходных файла: main.cpp, Example.h и Example.cpp. При попытке запустить его происходит сбой. Требуется выяснить причину и предложить исправление.
Файл main.cpp:
# include "Example.h"
int main()
{
Example e(1);
}
Файл Example.cpp:
# include "Example.h"
# include <vector>
struct Example::Impl
{
Impl(int i) : m_data(1 /* count */, i) {}
std::vector<int> m_data;
};
Example::Example(int i) :
m_impl(std::make_unique<Impl>(i))
{
}
Файл Example.h:
# pragma once
# include <memory>
class Example
{
public:
Example(int);
struct Impl;
std::unique_ptr<Impl> m_impl;
};
Задача: определить, почему программа завершается с ошибкой, и предложить корректный способ её исправления, учитывая правила использования std::unique_ptr с неполным типом.
Ответ
Это прежде всего ошибка компиляции, а не обязательный сбой при запуске: неявный деструктор Example использует default_delete для неполного Impl. Определите деструктор там, где Impl уже известен.
В Example.h добавьте объявление:
~Example();
В Example.cpp после полного определения struct Example::Impl добавьте:
Example::~Example() = default;
unique_ptr допускает хранение указателя на неполный тип, но удаление стандартным deleter требует полного определения. Если классу нужны перемещения, их также явно объявляют и определяют в .cpp: пользовательское объявление деструктора влияет на автоматическое создание move-операций.
Источник: eel.is.