Использование unique_ptr в классах с защищенными деструкторами
Я изучаю основанный на политике дизайн в Modern C++ Design, и я застрял в простом примере ниже, где я пытался использовать std::vector
из std::unique_ptr
s в моем шаблонном классе политики:
#include <memory>
#include <vector>
template <class T> struct MyPolicy {
MyPolicy() = default;
MyPolicy(std::size_t N) : myvec{std::vector<std::unique_ptr<T>>(N)} {
for (std::size_t i = 0; i < N; i++)
myvec[i].reset(new T(i));
}
// protected: // or, even, public:
// /*virtual*/ ~MyPolicy() = default;
private:
std::vector<std::unique_ptr<T>> myvec;
};
template <class T, template <class> class Policy>
struct Shell : public Policy<T> {
Shell() = default;
Shell(std::size_t N) : Policy<T>(N) {}
};
int main(int argc, char *argv[]) {
Shell<double, MyPolicy> s;
s = Shell<double, MyPolicy>(7);
Shell<double, MyPolicy> s2{6};
s = std::move(s2);
return 0;
}
Все работает хорошо выше. Однако подвох в том, что с MyPolicy
должен наследоваться от, его деструктор должен быть либо virtual
а также public
или неvirtual
а также protected
(по крайней мере, цитата из книги).
В приведенном выше примере, когда я раскомментирую строки, чтобы сделать их либо
public:
virtual ~MyPolicy() = default;
или же
protected:
~MyPolicy() = default;
код не компилируется. Я не могу понять, с чем связана проблема std::unique_ptr
в этом примере, так как тип T
не является неполным или чем-то, что имеет защищенный / частный деструктор.
Буду признателен за вашу помощь. Благодарю.
1 ответ
Объявление деструктора предотвращает неявное объявление конструктора перемещения и операторов присваивания перемещения. Таким образом, если вы объявляете виртуальный деструктор и хотите использовать специальные функции перемещения по умолчанию, вам необходимо явно объявить их самостоятельно:
public:
virtual ~MyPolicy() = default;
MyPolicy(MyPolicy&&) = default; //here
MyPolicy& operator= (MyPolicy&&) = default; //and here