Я не понимаю следующий сценарий. Речь идет об использовании идиомы pimpl, основанной на std::unique_ptr
в производном классе. Учитывая простую иерархию классов, указанную ниже:Pimpl с std :: unique_ptr в производном классе
class Foo
{
public:
virtual ~Foo();
//...
};
struct X;
class Bar : public Foo
{
public:
~Bar();
//...
private:
std::unique_ptr<X> _d;
};
Я показываю только код, имеющий отношение к моему вопросу.
Представьте себе класс Foo
, являющийся интерфейсом и классом «Бар», который его реализует. Я хочу использовать идиому pimpl в Bar
. Деструкторы являются виртуальными и определены в соответствующих файлах cpp. Также полное определение struct X
, которое объявлено только вперед, доступно в cpp, так что для деструктора Bar
может быть создан экземпляр destructor std::unique_ptr<X>::~unique_ptr()
. Когда я пытаюсь создать экземпляр Bar
, я бы ожидать, что она работает
int main()
{
Bar b;
}
Вместо этого, я получаю ошибку компиляции использования неопределенного типа «X» с последующим сообщением не может удалить неполный тип (в обновлении Visual Studio 2013 2). Однако, если я явно добавлю конструктор по умолчанию к Bar
, main()
компилирует/строит правильно.
class Foo
{
public:
virtual ~Foo();
};
struct X;
class Bar : public Foo
{
public:
Bar();
~Bar();
private:
std::unique_ptr<X> _d;
};
Я не видеть соответствие между наличием конструкторов по умолчанию в этой иерархии классов и полнотой struct X
в контексте std::unique_ptr<X>
в Bar
. Может ли кто-нибудь объяснить или указать на возможно уже существующее объяснение?
Вам действительно нужен деструктор для Bar в файле, где X объявлен, только. –
Боковое примечание, может быть, см. Это: https://stackoverflow.com/questions/24635255/is-it-possible-to-write-an-agile-pimpl-in-c/24638702#24638702 – Galik
«переключатель» добавляет конструктор в 'Bar', добавив его в' Foo', ничего не меняет – WorldSEnder