Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.68/120: Рейтинг темы: голосов - 120, средняя оценка - 4.68
749 / 352 / 72
Регистрация: 10.06.2014
Сообщений: 2,371
1

Что означают ключевые слова default, delete и зачем они нужны

16.01.2017, 13:51. Показов 23823. Ответов 22
Метки нет (Все метки)

Собственно сабж.
Часто встречаю что методу можно присвоить какое то значение, например virtual void method() = 0 означает что этот метод должен быть реализован наследником и у него нет тела в момент объявления.

Но что означает default и delete тогда когда они вместо нуля после функции?
Искал в тырнете, но плохо понял
Прошу пояснить кто знает, хочу знать где этим можно и даже нужно пользоваться

И ещё куда происходит присвоение? Метод же это не переменная что бы писать method() = 0
Где то под капотом есть указатель на этот метод и присвоение этого значения происходит именно этому указателю?

Добавлено через 1 минуту
Заголовок у меня плохой, модераторы, поправьте пожалуйста
Что означают ключевые слова default, delete в описании функции и зачем они нужны
Думаю так лучше
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
16.01.2017, 13:51
Ответы с готовыми решениями:

Что за векторы и зачем они нужны
Читал книгу по программированию на С++ и дошел до раздела векторы. Вот хотел у вас спросить за чем...

Что такое атрибуты и зачем они нужны?
Нужен человек, который может объяснить, что такое атрибуты и зачем они нужны, на как можно более...

Что такое классы и зачем они нужны?
Здравствуйте! Объясните ,что такое классы и зачем они нужны? Я прочитал кучу всего про классы, но...

Что такое комплекты инициализации и зачем они нужны?
Что такое комплекты инициализации и зачем они нужны? Например комплект инициализации к Xerox...

22
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
16.01.2017, 13:52 2
Цитата Сообщение от sys_beginner Посмотреть сообщение
virtual void method() = 0
Называется чисто виртуальная функция.
Цитата Сообщение от sys_beginner Посмотреть сообщение
default
Присвоить реализацию по умолчанию.
Цитата Сообщение от sys_beginner Посмотреть сообщение
delete
Пометить функцию как удалённую. Любое обращение к ней будет вызывать ошибку компиляции. Делаем это явно, а не костылим как в С++98, запихнув определение в Private секцию.
1
749 / 352 / 72
Регистрация: 10.06.2014
Сообщений: 2,371
16.01.2017, 13:57  [ТС] 3
Цитата Сообщение от MrGluck Посмотреть сообщение
Присвоить реализацию по умолчанию.
Читал такое и не понял. Компилятор же сам добавляет реализацию по умолчанию зачем это писать?

Цитата Сообщение от MrGluck Посмотреть сообщение
Пометить функцию как удалённую.
Правильно ли я понимаю это нужно использовать что бы:
1. Предотвратить обращение к методу использование которого не предусмотрено для объектов этого класса
2. Что бы компилятор не добавлял реализацию по умолчанию и исходный код стал меньше?
3. Это касается только тех методов которые компилятор генерирует по умолчанию?
0
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
16.01.2017, 13:58 4
Цитата Сообщение от sys_beginner Посмотреть сообщение
этим можно и даже нужно пользоваться
Пример с default:
Мы определяем явно какой-нибудь конструктор с параметрами. Но при этом хотим оставить конструктор по умолчанию, при этом нас устраивает стандартная его реализация. Мы можем объявить его, добавив на конце = default и всё, тело не нужно описывать явно, вдобавок это повышает вероятность, что читавший поймёт наши намерения.
Другой пример. Как нам известно, деструктор, генерируемый компилятором по умолчанию не виртуальный. Но если класс предполагает наследников, нам нужно сделать его виртуальным для правильного полиморфного удаления объекта. В классе не используется динамическая память и нас устраивает то, что компилятор сгенерирует по умолчанию. Мы объявляем деструктор явно, указав что он виртуальный и добавляем на конец = default, подчёркивая тем самым, что единственная причина определения явно - добавление виртуальности.
3
749 / 352 / 72
Регистрация: 10.06.2014
Сообщений: 2,371
16.01.2017, 13:58  [ТС] 5
И есть ли ещё ключевые слова для таких вещей кроме как delete default и 0?
0
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
16.01.2017, 13:58 6
Цитата Сообщение от sys_beginner Посмотреть сообщение
delete default
const override final
0
Эксперт С++
8556 / 4132 / 908
Регистрация: 15.11.2014
Сообщений: 9,330
16.01.2017, 13:59 7
Цитата Сообщение от sys_beginner Посмотреть сообщение
означает что этот метод должен быть реализован наследником и у него нет тела в момент объявления.
оно может не быть. а может и быть.
никто не запрещает написать тело для чисто-виртуальной функции.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
 
struct base
{
    // как известно, все без исключения объекты 
    // обязаны иметь деструктор
    virtual ~base() = 0;
};
 
base::~base()
{
    std::cout <<"base::base\n";
}
 
struct der: base{};
 
int main() 
{
    der d;
}
Цитата Сообщение от sys_beginner Посмотреть сообщение
default
указание компилятору,
что бы он сам создал реализацию по дефолту

Цитата Сообщение от sys_beginner Посмотреть сообщение
delete
что реализации нет.
например, если нужно запретить конструктор копии.
попытка сделать копию будет приводить к ошибке компиляции.

Цитата Сообщение от sys_beginner Посмотреть сообщение
И ещё куда происходит присвоение?
это не присвоение.
просто такой способ обозначить,
что функция - чисто-виртуальная.
1
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
16.01.2017, 14:05 8
Цитата Сообщение от sys_beginner Посмотреть сообщение
0
не ключевое слово, а способ пометить виртуальную функцию как чисто виртуальную. Это вообще отношения не имеет к теме keyword.

Добавлено через 1 минуту
Цитата Сообщение от sys_beginner Посмотреть сообщение
Компилятор же сам добавляет реализацию по умолчанию зачем это писать?
Есть случаи, когда компилятор не генерирует уже реализацию по умолчанию или нас не устраивает сигнатура, а реализация подходит. Примеры я указал выше.

Добавлено через 2 минуты
http://en.cppreference.com/w/c... _functions

Добавлено через 1 минуту
http://en.cppreference.com/w/c... _functions
1
749 / 352 / 72
Регистрация: 10.06.2014
Сообщений: 2,371
16.01.2017, 14:06  [ТС] 9
Цитата Сообщение от MrGluck Посмотреть сообщение
const override final
Это же вроде без присвоения пишется. Имелось ввиду именно там где между ключевым словом и функцией нет оператора присваивания

MrGluck,
Про default это всмысле когда мы создаем конструктор явно, конструктор по умолчанию не добавляется
Но если он нужен просто пишем defaultConstructor() = default и без описания тела просим компилятор его добавить
Так?

Цитата Сообщение от MrGluck Посмотреть сообщение
не ключевое слово, а способ пометить виртуальную функцию как чисто виртуальную. Это вообще отношения не имеет к теме keyword.
Ага. Просто для простоты изложения мысли обобщил

Цитата Сообщение от MrGluck Посмотреть сообщение
Есть случаи, когда компилятор не генерирует уже реализацию по умолчанию
А, понял. Это может произойти только в определенных ситуациях а не так что бы "может быть может не быть, зависит от погоды на марсе"... понял спасибо

Добавлено через 1 минуту
Цитата Сообщение от hoggy Посмотреть сообщение
никто не запрещает написать тело для чисто-виртуальной функции.
Тогда наверное и смысла нет отмечать её как виртуальную если нет наследников

Добавлено через 29 секунд
Цитата Сообщение от hoggy Посмотреть сообщение
попытка сделать копию будет приводить к ошибке компиляции
И исходного кода меньше будет, да?
0
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
16.01.2017, 14:12 10
Цитата Сообщение от sys_beginner Посмотреть сообщение
Имелось ввиду именно там где между ключевым словом и функцией нет оператора присваивания
Я привёл в пример ключевые слова. Если вы про возможные конструкции, которые могут идти после символа = при объявлении специального метода, то кроме приведённых трёх вариантов (default, delete, 0) я более не знаю. Хотя повторюсь, неправильно было бы ставить ноль с ключевыми словами в один ряд.

Добавлено через 24 секунды
Цитата Сообщение от sys_beginner Посмотреть сообщение
Но если он нужен просто пишем defaultConstructor() = default и без описания тела просим компилятор его добавить
Так?
Например так.

Добавлено через 2 минуты
Цитата Сообщение от sys_beginner Посмотреть сообщение
смысла нет отмечать её как виртуальную если нет наследников
Функцию помечают как виртуальную если она потенциально может иметь наследников.
Но там говорилось про другое. Чисто виртуальная функция - эта не просто функция, которая не имеет реализацию (как некоторые ошибочно полагают).
1
749 / 352 / 72
Регистрация: 10.06.2014
Сообщений: 2,371
16.01.2017, 14:13  [ТС] 11
MrGluck,
Спасибо что объяснили.

Цитата Сообщение от MrGluck Посмотреть сообщение
Хотя повторюсь, неправильно было бы ставить ноль с ключевыми словами в один ряд.
Согласен)) Просто так проще выразиться, а народ здесь подкованный, сразу понимает о чем речь

Добавлено через 33 секунды
Цитата Сообщение от MrGluck Посмотреть сообщение
Но там говорилось про другое. Чисто виртуальная функция - эта не просто функция, которая не имеет реализацию (как некоторые ошибочно полагают).
Дошло

Добавлено через 37 секунд
Так а кода все таки меньше генерируется если использовать delete?
0
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
16.01.2017, 14:20 12
Касаемо ситуации с виртуальным деструктором (на всякий случай хочу разъяснить).
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
struct base
{
    //virtual
    ~base() = default;
};
 
struct der: base
{
    ~der() { std::cout << "der::der\n"; }
};
 
int main()
{
    base *d = new der;
    delete d;
}
Для вызова деструктора производного класса при удалении объекта производного класса размещённого динамически через указатель на базовый класс, необходимо раскомментировать 5 строку.

Добавлено через 1 минуту
Цитата Сообщение от sys_beginner Посмотреть сообщение
Так а кода все таки меньше генерируется если использовать delete?
Учитывая, что это ключевое слово влияет только на компиляцию - одинаково. То есть есть обращение - delete не даст скомпилировать. Нет обращения - и генерировать нечего.
1
749 / 352 / 72
Регистрация: 10.06.2014
Сообщений: 2,371
16.01.2017, 14:25  [ТС] 13
Цитата Сообщение от MrGluck Посмотреть сообщение
~base() = default;
А разве не нужно писать ключевое слово virtual перед ~?
0
Эксперт С++
8556 / 4132 / 908
Регистрация: 15.11.2014
Сообщений: 9,330
16.01.2017, 14:26 14
Цитата Сообщение от sys_beginner Посмотреть сообщение
Тогда наверное и смысла нет отмечать её как виртуальную если нет наследников
разумеется.
виртуальные функции пишутся виртуальными именно в расчете на то,
что наследники будут.

Цитата Сообщение от sys_beginner Посмотреть сообщение
И исходного кода меньше будет, да?
даже не знаю, как отвечать на такой нелогичный вопрос.

исходного кода будет ровно столько,
сколько вы сами его напишите.
0
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
16.01.2017, 14:27 15
Цитата Сообщение от sys_beginner Посмотреть сообщение
А разве не нужно писать ключевое слово virtual перед ~?
В примере демонстрируется что будет если его не написать. Как бы ключевое слово специально поставлено в комментариях.
0
749 / 352 / 72
Регистрация: 10.06.2014
Сообщений: 2,371
16.01.2017, 14:30  [ТС] 16
Цитата Сообщение от hoggy Посмотреть сообщение
исходного кода будет ровно столько,
сколько вы сами его напишите.
Имелось ввиду исполняемый код
Читал в разных местах что компилятор может выбрасывать то что не нужно
Вот и подумал если реализация по умолчанию объявляется delete
То выбросит ли компилятор (или просто не сгенерирует) код который генерировал по умолчанию?

Добавлено через 2 минуты
Цитата Сообщение от MrGluck Посмотреть сообщение
В примере демонстрируется что будет если его не написать.
))) Понял. Об этом читал ещё где то пол годика назад. Но за пример все равно спасибо
Память освежаю
0
Эксперт С++
8556 / 4132 / 908
Регистрация: 15.11.2014
Сообщений: 9,330
16.01.2017, 14:31 17
Цитата Сообщение от sys_beginner Посмотреть сообщение
Вот и подумал если реализация по умолчанию объявляется delete
То выбросит ли компилятор (или просто не сгенерирует) код который генерировал по умолчанию?
конечно выбросит.
1
749 / 352 / 72
Регистрация: 10.06.2014
Сообщений: 2,371
16.01.2017, 14:56  [ТС] 18
MrGluck, hoggy,
Подскажите пожауйлста, где можно посмотреть какие методы компилятор генерирует автоматически и их сигнатуры что бы смотреть на список и исключать то что не нужно c помощью delete?

Например для классов которые содержат только простые типы насколько понимаю не нужен конструктор перемещения
и хотелось бы не полагаться на то что "компилятор может понять что не нужно его генерировать или не понять" а явно удалить так же и остальными автоматически генерируемыми методами и так понятнее будет выглядеть код
0
Эксперт С++
8556 / 4132 / 908
Регистрация: 15.11.2014
Сообщений: 9,330
16.01.2017, 15:02 19
Цитата Сообщение от sys_beginner Посмотреть сообщение
Подскажите пожауйлста, где можно посмотреть какие методы компилятор генерирует автоматически и их сигнатуры
в стандарте языка

Цитата Сообщение от sys_beginner Посмотреть сообщение
и исключать то что не нужно c помощью delete?
исключать нужно лишь то, что способно нарушить работу.
все остальное - проблемы компилятора.
1
Форумчанин
Эксперт CЭксперт С++
8170 / 5020 / 1436
Регистрация: 29.11.2010
Сообщений: 13,453
16.01.2017, 15:12 20
Лучший ответ Сообщение было отмечено Undisputed как решение

Решение

Цитата Сообщение от sys_beginner Посмотреть сообщение
где можно посмотреть какие методы компилятор генерирует автоматически и их сигнатуры что бы смотреть на список и исключать то что не нужно c помощью delete?
В стандарте. Глава 12 Special member functions
Есть, например, правило трёх (начиная с С++11 некоторые ещё определяют правило пяти, с версиями rvalue):
Если в классе идёт работа с динамической памятью, в нём необходимо явно определить конструктор копий, оператор присваиваний и деструктор.
Для того, чтобы понять нужно ли описывать специальные методы класса явно или хватит реализации по умолчанию, необходимо хорошо понять как устроена реализация по умолчанию. Это и принципы генерации (при каком условии что генерируется, а что нет), указано в стандарте.

Добавлено через 7 минут
Выдержка из стандарта насчёт генерации специальных методов класса

Конструктор по умолчанию:
12.1 Constructors
4. A default constructor for a class X is a constructor of class X that can be called without an argument. If
there is no user-declared constructor for class X, a constructor having no parameters is implicitly declared
as defaulted (8.4). An implicitly-declared default constructor is an inline public member of its class. A
defaulted default constructor for class X is defined as deleted if:
— X is a union-like class that has a variant member with a non-trivial default constructor,
— any non-static data member with no brace-or-equal-initializer is of reference type,
— any non-variant non-static data member of const-qualified type (or array thereof) with no brace-or
equal-initializer does not have a user-provided default constructor,
— X is a union and all of its variant members are of const-qualified type (or array thereof),
— X is a non-union class and all members of any anonymous union member are of const-qualified type
(or array thereof),
— any direct or virtual base class, or non-static data member with no brace-or-equal-initializer , has class
type M (or array thereof) and either M has no default constructor or overload resolution (13.3) as applied
to M’s default constructor results in an ambiguity or in a function that is deleted or inaccessible from
the defaulted default constructor, or
— any direct or virtual base class or non-static data member has a type with a destructor that is deleted
or inaccessible from the defaulted default constructor. <...>

5. A default constructor that is defaulted and not defined as deleted is implicitly defined when it is odr
used (3.2) to create an object of its class type (1.8) or when it is explicitly defaulted after its first declaration. <...>
Конструктор копий:
12.8 Copying and moving class objects
7. If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class
definition declares a move constructor or move assignment operator, the implicitly declared copy constructor
is defined as deleted; otherwise, it is defined as defaulted
Конструктор присваиваний:
12.8 Copying and moving class objects
9. If the definition of a class X does not explicitly declare a move constructor, one will be implicitly declared
as defaulted if and only if
— X does not have a user-declared copy constructor,
— X does not have a user-declared copy assignment operator,
— X does not have a user-declared move assignment operator, and
— X does not have a user-declared destructor.
[ Note: When the move constructor is not implicitly declared or explicitly supplied, expressions that
otherwise would have invoked the move constructor may instead invoke a copy constructor. — end note ]
Оператор присваиваний с копированием:
12.8 Copying and moving class objects
18. If the class definition does not explicitly declare a copy assignment operator, one is declared implicitly. If
the class definition declares a move constructor or move assignment operator, the implicitly declared copy
assignment operator is defined as deleted; otherwise, it is defined as defaulted (8.4). The latter case is
deprecated if the class has a user-declared copy constructor or a user-declared destructor.
Оператор присваиваний с перемещением:
12.8 Copying and moving class objects
20. If the definition of a class X does not explicitly declare a move assignment operator, one will be implicitly
declared as defaulted if and only if
— X does not have a user-declared copy constructor,
— X does not have a user-declared move constructor,
— X does not have a user-declared copy assignment operator, and
— X does not have a user-declared destructor
Деструктор:
12.4 Destructors
4. If a class has no user-declared destructor, a destructor is implicitly declared as defaulted (8.4). An implicitly
declared destructor is an inline public member of its class.

5. A defaulted destructor for a class X is defined as deleted if:
— X is a union-like class that has a variant member with a non-trivial destructor,
— any of the non-static data members has class type M (or array thereof) and M has a deleted destructor
or a destructor that is inaccessible from the defaulted destructor,
— any direct or virtual base class has a deleted destructor or a destructor that is inaccessible from the
defaulted destructor,
— or, for a virtual destructor, lookup of the non-array deallocation function results in an ambiguity or in
a function that is deleted or inaccessible from the defaulted destructor. <...>
2
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
16.01.2017, 15:12

Что такое абстрактные классы и зачем они нужны?
Добрый день, форум, решил немного расширить свои знания c# и начал с абстрактных классов(раньше...

Что такое атрибуты (dir) и зачем они нужны ?
может быть кто нибутъ объяснит что такое атрибуты и зачем они нужны ? a=1 a Out: 1 dir(a)...

Что такое hash-таблицы, и зачем они нужны?
Обьясните пожалуста по простому что такое хеш таблици и зачем они надо... пытался разобратся с ними...

Что такое указатели? Зачем они нужны и их практичное применение
Здравствуйте, подскажи пожалуйста зачем нужны указатели и в чем их смысл??? Ссылки на другие...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.