правило нуля против деструкторов базового класса

У меня есть базовый класс Base и производный класс D, и я хотел бы, чтобы конструктор перемещения и оператор присваивания перемещения автоматически генерировались компилятором для меня. После Правило нуля, Я оставляю все управление памятью компилятору и использую только классы уровня 2 (без сырых указателей, массивов и т. Д.):

#include <iostream>

class Base{
public:
Base(): a_(42) {}
virtual void show() { std::cout << "Base " << a_ << std::endl; }

private:
int a_;
};

class D : Base {
public:
D(): b_(666) {}
void show() { std::cout << "D " << b_ << std::endl; }

private:
int b_;
};

int main() {
Base b;
b.show();
D d;
d.show();
return 0;
}

Это должно быть так, верно?

Войти основные принципы C ++:

Деструктор базового класса должен быть либо общедоступным и виртуальным, либо защищенным и не виртуальным.

Ах, я думаю, мне придется добавить деструктор Base, Но это покончит с автоматически генерируемыми функциями перемещения!

Какой тут чистый выход?

3

Решение

Вы можете = default все, что вы хотели бы сгенерировать компилятором.
Смотрите (внизу): http://en.cppreference.com/w/cpp/language/rule_of_three

В вашем случае это может выглядеть примерно так:

class Base{
public:
Base(): a_(42) {}
Base(const Base&) = default;
Base(Base&&) = default;
Base& operator=(const Base&) = default;
Base& operator=(Base&&) = default;
virtual ~Base() = default;

virtual void show() { std::cout << "Base " << a_ << std::endl; }

private:
int a_;
};
7

Другие решения

Вы можете создать один раз, как класс

struct VirtualBase
{
virtual ~VirtualBase() = default;
VirtualBase() = default;
VirtualBase(const VirtualBase&) = default;
VirtualBase(VirtualBase&&) = default;
VirtualBase& operator = (const VirtualBase&) = default;
VirtualBase& operator = (VirtualBase&&) = default;
};

А затем следуйте правилу нуля:

class Base : VirtualBase
{
public:
Base(): a_(42) {}
virtual void show() { std::cout << "Base " << a_ << std::endl; }

private:
int a_;
};
2

По вопросам рекламы [email protected]