Страницы

Поиск по вопросам

пятница, 14 февраля 2020 г.

C++ добавление (= default/delete) в конце функции

#cpp


Описывается, что если указать void func() = delete/default, то это указывает, что
компилятор сам должен сгенерировать код для этой функции и именно он будет использоваться. 

Момент с генерацией кода компилятором совсем не понятный. 
Может кто объяснить доступным языком, что именно за код будет сгенерирован, что это
означает и что использовалось до того как появились = default/delete? 
кроме того, если я допишу в конце деструктора = default, это будет означать, что
он виртуальный? 
    


Ответы

Ответ 1



Определение функции как 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 возможно для любых функций, но с этим такого вопроса не возникает.

Комментариев нет:

Отправить комментарий