Описывается, что если указать void func() = delete/default, то это указывает, что компилятор сам должен сгенерировать код для этой функции и именно он будет использоваться.
Момент с генерацией кода компилятором совсем не понятный.
Может кто объяснить доступным языком, что именно за код будет сгенерирован, что это означает и что использовалось до того как появились = default/delete?
кроме того, если я допишу в конце деструктора = default, это будет означать, что он виртуальный?
Ответ
Определение функции как default возможно только для специальных функций-членов класса: конструкторов, деструкторов и операторов присваивания. Определяться эти функции будут так, как они неявно определялись испокон веков - через делегирование соответствующих действий каждому полю класса. Произвольную постороннюю функцию нельзя просто взять и определить, как default
Польза от возможности такого определения происходит в первую очередь из того, что в С++11 явное объявление перемещающего конструктора копирования или оператора присваивания подавляет неявное объявление/определение всех остальных функций из Правила Пяти (и наоборот). А в будущем объявление вообще любой функции из Правила Пяти будет подавлять объявление всех остальных функций Правила Пяти. Чтобы в такой ситуации "спасти" потерянные объявления/определения (если они вас устраивают) как раз и подходит default
struct S
{
S& operator =(S &&) { return *this; }
// Подавляет неявное объявление копирующего оператора присваивания
};
int main()
{
S s, t;
s = t; // Ошибка - нет копирующего оператора присваивания
}
Чтобы "восстановить" работоспособность этого кода достаточно добавить в класс
S& operator =(const S&) = default;
Некоторые тонкости зависят от того, где именно функция определена как default. Если такое определение сделано в точке первого объявления в классе, то такая функция ничем не отличается от неявно определенной функции - она не считается предоставленной пользователем (user-provided). А вот если функция была сначала объявлена в классе, а затем определена как default за пределами класса, то такая функция является предоставленной пользователем. Это влияет на такие свойства класса, как агрегатность и пр.
struct S
{
int i;
S() = default;
};
struct T
{
int i;
T();
};
T::T() = default;
// Класс `S` по-прежнему является агрегатом, а вот класс `T`
// агрегатом не является
int main()
{
S s = { 1 }; // Все в порядке, обычная агрегатная инициализация
T t = { 1 }; // Ошибка, агрегатная инициализация недоступна
}
Описание деструктора как default никак не влияет на его виртуальность.
Определение как delete возможно для любых функций, но с этим такого вопроса не возникает.
Комментариев нет:
Отправить комментарий