Конструктор по умолчанию
Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy — урок 18 из 104.
Конструктор по умолчанию — это конструктор, который можно вызвать без аргументов. Он инициализирует объект, когда начальные значения не предоставлены. Каждому классу необходим способ создания объектов в допустимом состоянии по умолчанию.
Если вы не определите ни одного конструктора, компилятор генерирует неявный конструктор по умолчанию, который ничего не делает для примитивных типов и вызывает конструкторы по умолчанию для объектов-членов.
class Player {
int health;
int score;
public:
Player() { // Конструктор по умолчанию
health = 100;
score = 0;
}
};
Player p1; // Вызывает конструктор по умолчанию
Player p2{}; // Также вызывает конструктор по умолчаниюКак только вы определяете любой конструктор (например, параметризованный), компилятор больше не генерирует конструктор по умолчанию. Вы должны явно определить его, если он вам все еще нужен.
class Enemy {
int damage;
public:
Enemy(int d) : damage(d) {} // Только параметризованный конструктор
};
Enemy e1(10); // Работает
Enemy e2; // Ошибка! Нет конструктора по умолчаниюВ современном C++ вы можете явно запросить генерируемый компилятором конструктор по умолчанию, используя = default:
class Item {
int id;
public:
Item() = default; // Компилятор генерирует конструктор по умолчанию
Item(int i) : id(i) {}
};Конструкторы по умолчанию необходимы для создания массивов объектов и для классов, используемых в контейнерах, таких как std::vector, которым может потребоваться создание элементов без аргументов.
Задание
ЛегкоДавайте создадим простую систему счетчиков, которая демонстрирует, как конструкторы по умолчанию инициализируют объекты в допустимое начальное состояние.
Вы создадите два файла для организации вашего кода:
Counter.h: Определите классCounter, который отслеживает значение счетчика. Ваш класс должен иметь:- Приватный атрибут
count(целое число) - Приватный атрибут
name(строка) для идентификации счетчика - Конструктор по умолчанию, который инициализирует
countзначением0иnameзначением"Unnamed", а затем выводит"Counter created: <name>" - Метод
increment(), который увеличивает счетчик на 1 - Метод
getCount(), который возвращает текущее значение счетчика - Метод
getName(), который возвращает имя счетчика
- Приватный атрибут
main.cpp: Продемонстрируйте, что конструкторы по умолчанию работают при создании объектов различными способами. Считайте из входных данных число, указывающее, сколько раз нужно увеличить счетчик, затем:- Создайте Counter, используя прямую инициализацию:
Counter c1; - Создайте еще один Counter, используя инициализацию в фигурных скобках:
Counter c2{}; - Увеличьте
c1количество раз, указанное во входных данных - Выведите
"<name>: <count>"для c1 - Выведите
"<name>: <count>"для c2
- Создайте Counter, используя прямую инициализацию:
Оба счетчика должны начинаться с 0 благодаря вашему конструктору по умолчанию, но увеличиваться будет только c1. Это показывает, как конструкторы по умолчанию гарантируют, что каждый объект начинает работу в предсказуемом, валидном состоянии, независимо от того, как он был создан.
Подключите ваш заголовочный файл в main.cpp с помощью #include "Counter.h".
Шпаргалка
Конструктор по умолчанию — это конструктор, который можно вызвать без аргументов. Он инициализирует объект, когда начальные значения не предоставлены.
class Player {
int health;
int score;
public:
Player() { // Default constructor
health = 100;
score = 0;
}
};
Player p1; // Calls default constructor
Player p2{}; // Also calls default constructorЕсли вы не определите ни одного конструктора, компилятор создаст неявный конструктор по умолчанию. Однако, как только вы определите любой конструктор (например, параметризованный), компилятор больше не будет автоматически создавать конструктор по умолчанию.
class Enemy {
int damage;
public:
Enemy(int d) : damage(d) {} // Parameterized constructor only
};
Enemy e1(10); // Works
Enemy e2; // Error! No default constructorВы можете явно запросить создание конструктора по умолчанию компилятором, используя = default:
class Item {
int id;
public:
Item() = default; // Compiler generates default constructor
Item(int i) : id(i) {}
};Конструкторы по умолчанию необходимы для создания массивов объектов и для классов, используемых в контейнерах, таких как std::vector.
Попробуйте сами
#include <iostream>
#include "Counter.h"
using namespace std;
int main() {
// Считать количество инкрементаций
int n;
cin >> n;
// TODO: Создать Counter, используя прямую инициализацию: Counter c1;
// TODO: Создать еще один Counter, используя инициализацию фигурными скобками: Counter c2{};
// TODO: Увеличить c1 на число, указанное в n
// TODO: Вывести "<name>: <count>" для c1
// TODO: Вывести "<name>: <count>" для c2
return 0;
}
В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.
Все уроки раздела Объектно-ориентированное программирование
1Основы ООП
Внешние файлыСборка и компиляция C++Заголовочные файлы и файлы исходного кодаПространства имен и область видимостиВведение в ООП на C++Классы и объектыУказатель 'this'Методы (функции-члены)Атрибуты (члены данных)Основы конструкторов и деструкторовИтоги — Простой калькулятор4Свойства классов
Члены экземпляра против статическихГеттеры и сеттерыКонстантные функции-членыКлючевое слово mutableСтатические методы и переменныеДружественные функции и классыИтоги — Менеджер банковских счетов7Наследование
Основы наследованияУровни доступа при наследованииПорядок вызова конструкторов и деструкторовПереопределение методовВиртуальные функции и VTableМножественное наследованиеВиртуальное наследованиеИтоги — Иерархия сотрудников10Обзор STL
Обзор и философия STLКонтейнеры STLИтераторыАлгоритмы STLФункторы и лямбда-выраженияИтоги: частота слов13Паттерны проектирования. Часть 1
Введение в паттерны проектированияПаттерн SingletonFactory и Abstract FactoryПаттерн BuilderПаттерн ObserverПаттерн Strategy2Управление памятью
Стек и кучаУказатели и ссылкиДинамическая память (new/delete)Умные указатели в C++RAII в C++Итоги — Менеджер динамического массива5Инкапсуляция
Спецификаторы доступа в C++Спецификаторы доступа: подробный разборСокрытие данныхStruct против ClassВложенные и внутренние классыИтоги — Система учета студентов8Полиморфизм
Полиморфизм компиляции и времени выполненияПерегрузка функцийВиртуальные функции: повторениеЧистые виртуальные функцииАбстрактные классыПроектирование интерфейсов на C++Dynamic Casting и RTTIИтоги: Калькулятор фигур11Продвинутые концепции ООП
Композиция против наследованияМиксины через CRTPИдиома PimplСтирание типовEnum Classes и строгая типизацияОбработка исключений в ООППользовательские иерархии исключений14Паттерны проектирования. Часть 2
Паттерн КомандаПаттерн АдаптерПаттерн ДекораторПаттерн Шаблонный методПаттерн СостояниеПаттерн КомпоновщикRAII как паттерн3Конструкторы и деструкторы
Конструктор по умолчаниюПараметризованный конструкторКонструктор копированияКонструктор перемещенияСписки инициализации конструктораДелегирующие конструкторыГлубокое погружение в деструкторыПравило трех / пяти / нуляПовторение — класс String6Перегрузка операторов
Введение в перегрузку операторовПерегрузка арифметических операторовПерегрузка операторов сравненияОператоры потоковПерегрузка оператора присваиванияПерегрузка операторов [] и ()Операторы преобразования типовИтоги — класс Matrix9Шаблоны
Шаблоны функцийШаблоны классовСпециализация шаблоновВариативные шаблоныОсновы SFINAE и Type TraitsИтоги — Обобщенный контейнер