std :: unique_ptr с неполным типом pimpl удивительно хорошо компилируется, когда его хост-класс используется полиморфно - PullRequest
2 голосов
/ 08 ноября 2019

У меня есть класс foo, производный от base, и, следовательно, виртуальный деструктор. Класс foo реализует идиому pimpl с std::unique_ptr неполного типа foo::impl. Как вы можете видеть из приведенного ниже кода, он не скомпилируется должным образом, если я попытаюсь удалить экземпляр foo, потому что std::unique_ptr должен знать foo::impl. С другой стороны, компилируется , когда я удаляю его через базовый класс. Я не понимаю, почему это так, и что более важно, я хотел бы знать, если это неопределенное поведение.

// Header.h
#pragma once

#include <memory>

class Base
{
public:
  virtual ~Base() =default;
};

class foo: public Base
{
public:
  foo();

private:
  class impl;
  std::unique_ptr<impl> p_;
};
// Source.cpp
#include "Header.h"

class foo::impl
{
};

foo::foo():p_(std::make_unique<foo::impl>()) {};
// main.cpp
#include "Header.h"

int main()
{
  std::unique_ptr<Base> t = std::make_unique<foo>(); // this one compiles and links and I would have expected it not to.

  //foo b; // this one does not compile as expected
  return 1;
}

У меня такие же результаты с Visual Studio 2013 и Visual Studio2017.

...