Средства обобщений
При написании обобщенного кода иногда важно провести различие между типами значений и ссылочными типами. Такая потребность возникает, в частности, в том случае, если переменной параметра типа должно быть присвоено значение по умолчанию. Для ссылочных типов значением по умолчанию является null, для неструктурных типов значений — 0 или логическое значение false, если это тип bool, а для структур типа struct — объект соответствующей структуры с полями, установленными по умолчанию. В этой связи возникает вопрос: какое значение следует присваивать по умолчанию переменной параметра типа: null, 0 или нечто другое?
Например, если в следующем объявлении класса Test:
переменной obj требуется присвоить значение по умолчанию, то какой из двух вариантов следует выбрать?:
Для разрешения этой дилеммы можно воспользоваться формой оператора default, приведенной ниже:
Эта форма оператора default пригодна для всех аргументов типа, будь то типы значений или ссылочные типы. Давайте рассмотрим пример:

Статические члены
Статические члены обобщенных классов требуют особого внимания. Статические члены обобщенного класса разделяются только одним экземпляром класса. Рассмотрим пример, в котором класс StaticDemo<T> содержит статическое поле х:
Поскольку класс StaticDemo<T> используется как с типом string, так и с типом int, существуют два набора статических полей:
Name already in use
docs / docs / csharp / language-reference / operators / default.md
- Go to file T
- Go to line L
- Copy path
- Copy permalink
- Open with Desktop
- View raw
- Copy raw contents Copy raw contents
Copy raw contents
Copy raw contents
default value expressions — produce the default value
A default value expression produces the default value of a type. There are two kinds of default value expressions: the default operator call and a default literal.
You also use the default keyword as the default case label within a switch statement.
The argument to the default operator must be the name of a type or a type parameter, as the following example shows:
You can use the default literal to produce the default value of a type when the compiler can infer the expression type. The default literal expression produces the same value as the default(T) expression where T is the inferred type. You can use the default literal in any of the following cases:
- In the assignment or initialization of a variable.
- In the declaration of the default value for an optional method parameter.
- In a method call to provide an argument value.
- In a return statement or as an expression in an expression-bodied member.
The following example shows the usage of the default literal:
[!TIP] Use .NET style rule IDE0034 to specify a preference on the use of the default literal in your codebase.
Ключевые слова default , delete . Примеры использования
Ключевое слово default введено в C++ 11. Его использование указывает компилятору самостоятельно генерировать (использовать) соответствующую функцию класса, если таковая не объявлена в классе.
Как известно, компилятор автоматически генерирует ряд конструкторов класса и деструктор. Указание ключевого слова default для этих функций дает следующие взаимосвязанные преимущества:
- программист получает понятную информацию об отсутствии реализации отдельных функций в классе. Используються компиляторные версии этих функций;
- упрощается восприятие информации об особенностях использования тех или иных функций класса. Вместо того чтобы вспоминать правила программист указывает то, что хочет получить.
Общая форма использования ключевого слова default для конструкторов класса следующая:
- ClassName – имя класса, в котором использовано ключевое слово default ;
- ClassName(parameters) – один из конструкторов класса, которые автоматически генерируются компилятором;
- parameters – список параметров, который принимает специальная функция класса, которая генерируется автоматически. Список параметров может отсутствовать (конструктор по умолчанию).
Общая форма использования ключевого слова default для деструктора класса
2. К каким специальным функциям класса может быть применено ключевое слово default ?
Ключевое слово default может применяться только к специальным функциям класса, которые при объявлении класса генерируются компилятором автоматически. К таким функциям относятся:
- конструктор по умолчанию (default constructor);
- конструктор копирования (copy constructor);
- конструктор перемещения (move constructor);
- оператор присваивания копированием (copy assignment operator);
- оператор присваивания перемещением (move assignment operator);
- деструктор (destructor).
3. Пример использования ключевого слова default для специальных функций класса, которые генерируются компилятором автоматически
Ниже продемонстрировано использование ключевого слова default для всех специальных функций класса, которые генерируются автоматически.
Объявляется класс Float , реализующий вещественное число.
В классе объявляются:
- внутренняя скрытая ( private ) переменная x ;
- default-конструктор по умолчанию;
- default-конструктор копирования;
- default-конструктор перемещения;
- default-оператор присваивания, выполняющий копирование;
- default-оператор присваивания, выполняющий перемещение;
- default-деструктор;
- методы доступа Get() , Set() .
- parametes1 , parameters2 , …, parametersN – список параметров соответствующего конструктора класса.
Параметры могут отсутствовать. Если параметры конструктора отсутствуют, то запрещено использовать конструктор по умолчанию. В этом случае при объявлении
компилятор будет выдавать ошибку
Ключевое слово delete может быть запрещено также и в методах. В этом случае, для метода с именем Func() общая форма объявления будет следующая
- Func() – имя функции которую нужно запретить использовать в классе;
- parameters – параметры функции;
- return_type – тип, возвращаемый функцией.
5. Пример использования ключевого слова delete в классе
Задан класс Point реализующий точку на плоскости. В классе объявляются следующие элементы:
-
- внутренние скрытые ( private ) переменные с именами x , y – координаты точки;
- конструктор по умолчанию Point() , обозначенный ключевым словом default . Ключевое слово default указывает, что должен выполняться неявный конструктор по умолчанию, который автоматически генерируется компилятором;
- конструктор Point(int) с одним параметром типа int ;
- конструктор с двумя параметрами Point(int, int) ;
- методы доступа GetX() , GetY() , SetX() , SetY() ;
- операторная функция operator+() , перегружающая бинарный оператор + ;
- операторная функция operator-() , перегружающая унарный оператор – .
В классе запрещается использовать конструктор с одним параметром Point(double) , принимающий параметр типа double . Этот конструктор обозначен ключевым словом delete . Однако, конструктор с параметром типа int разрешено использовать в классе.
Также запрещается использовать некоторые функции:
- функцию SetX(double) с параметром типа double . Однако, Set(int) с параметром типа int разрешается использовать;
- функцию SetXY(int, int) с двумя параметрами типа int .
Текст класса Point следующий:
Объясним некоторые фрагменты кода. Если в функции main() указать
то компилятор выдаст ошибку
Это означает, что запрещено использовать конструктор с 1 параметром типа double . Однако, разрешено использовать конструктор с 1 параметром типа int , так как этот конструктор указан без ключевого слова delete .
В классе Point ключевое слово delete также применяется к функции
Это означает, что запрещено вызывать функцию SetX() с параметром типа double . Однако класс содержит другую функцию SetX() с параметром типа int
которую разрешено вызывать. Таким образом в функции SetX() запрещается автоматическое приведение из типа double в тип int . По подобному примеру можно запретить автоматическое приведение типов для любых функций классов.
В демонстрационных целях показано, что в классе Point запрещено использовать функцию SetXY() с двумя параметрами
Хотя, другой реализации данной функции в классе нет. Подобные запреты не реализованных функций в классе нормально воспринимаются компилятором.
What does "default" mean after a class' function declaration?
I’ve seen default used next to function declarations in a class. What does it do?
5 Answers 5
It means that you want to use the compiler-generated version of that function, so you don’t need to specify a body.
You can also use = delete to specify that you don’t want the compiler to generate that function automatically.
With the introduction of move constructors and move assignment operators, the rules for when automatic versions of constructors, destructors and assignment operators are generated has become quite complex. Using = default and = delete makes things easier as you don’t need to remember the rules: you just say what you want to happen.
This is a new C++0x feature that tells the compiler to create the default version of the respective constructor or assignment operator, i.e. the one which just performs the copy or move action for each member. This is useful because the move constructor isn’t always generated by default (e.g. if you have a custom destructor), unlike the copy constructor (and likewise for assignment), but if there’s nothing non-trivial to write, it’s better to let the compiler handle it than to spell it out yourself each time.
Also notice that a default constructor would not be generated if you provide any other non-default constructor. If you still want the default constructor, too, you can use this syntax to have the compiler make one.