Параметризованный конструктор
Часть раздела Объектно-ориентированное программирование путешествия по C++ на Coddy — урок 19 из 104.
Параметризованный конструктор принимает аргументы, которые позволяют инициализировать объект конкретными значениями в момент создания. Вместо того чтобы полагаться на значения по умолчанию, вы можете настраивать начальное состояние каждого объекта.
class Player {
std::string name;
int health;
int level;
public:
Player(std::string n, int h, int lvl) {
name = n;
health = h;
level = lvl;
}
};
Player hero("Archer", 100, 5);
Player mage("Wizard", 80, 7);Вы можете определить несколько параметризованных конструкторов с различными списками параметров. Это называется перегрузкой конструкторов, и компилятор выбирает подходящий на основе предоставленных вами аргументов.
class Rectangle {
int width, height;
public:
Rectangle(int side) { // Квадрат
width = height = side;
}
Rectangle(int w, int h) { // Прямоугольник
width = w;
height = h;
}
};
Rectangle square(10); // Вызывает первый конструктор
Rectangle rect(10, 20); // Вызывает второй конструкторПараметры могут иметь значения по умолчанию, что делает некоторые аргументы необязательными. Это снижает необходимость в множественных перегруженных конструкторах.
class Enemy {
std::string type;
int damage;
public:
Enemy(std::string t, int d = 10) : type(t), damage(d) {}
};
Enemy goblin("Goblin"); // урон по умолчанию равен 10
Enemy dragon("Dragon", 50); // урон установлен на 50Вспомните из предыдущего урока: как только вы определяете параметризованный конструктор, компилятор больше не создает конструктор по умолчанию автоматически. Если вам нужны оба, вы должны определить конструктор по умолчанию явно.
Задание
ЛегкоДавайте создадим систему инвентаризации товаров, которая продемонстрирует, как параметризованные конструкторы позволяют создавать объекты с конкретными начальными значениями, и как перегрузка конструкторов обеспечивает гибкость при создании объектов.
Вы создадите два файла для организации вашего кода:
Product.h: Определите классProduct, который представляет товары в инвентаре. Ваш класс должен содержать:- Приватные атрибуты для
name(string),price(double) иquantity(integer) - Конструктор, который принимает все три параметра (name, price, quantity) для полной инициализации товара
- Конструктор, который принимает только name и price, при этом quantity по умолчанию равно
1 - Конструктор, который принимает только name, при этом price по умолчанию равно
0.0, а quantity по умолчанию равно0 - Метод
display(), который выводит информацию о товаре в формате:"<name>: "<name>: $<price> (x<quantity>)"lt;price> (x<quantity>)" - Метод
getTotalValue(), который возвращает цену, умноженную на количество
- Приватные атрибуты для
main.cpp: Продемонстрируйте работу всех трех конструкторов, считывая входные данные и создавая товары разными способами. Считайте из входного потока следующее:- Первая строка: название товара, цена и количество (разделенные пробелом)
- Вторая строка: название товара и цена (разделенные пробелом)
- Третья строка: только название товара
display()для каждого из них, а затем выведите общую стоимость всех трех товаров вместе в формате:"Total inventory value: "Total inventory value: $<value>"lt;value>"
Для вывода цены используйте один десятичный знак. Например, если вы создаете товар "Laptop" с ценой 999.99 и количеством 5, метод display должен показать "Laptop: $999.99 (x5)".
Подключите ваш заголовочный файл в main.cpp с помощью #include "Product.h".
Шпаргалка
Параметризованный конструктор принимает аргументы для инициализации объекта конкретными значениями во время его создания:
class Player {
std::string name;
int health;
int level;
public:
Player(std::string n, int h, int lvl) {
name = n;
health = h;
level = lvl;
}
};
Player hero("Archer", 100, 5);Перегрузка конструкторов позволяет создавать несколько конструкторов с различными списками параметров:
class Rectangle {
int width, height;
public:
Rectangle(int side) { // Квадрат
width = height = side;
}
Rectangle(int w, int h) { // Прямоугольник
width = w;
height = h;
}
};
Rectangle square(10); // Вызывает первый конструктор
Rectangle rect(10, 20); // Вызывает второй конструкторЗначения параметров по умолчанию делают аргументы необязательными:
class Enemy {
std::string type;
int damage;
public:
Enemy(std::string t, int d = 10) : type(t), damage(d) {}
};
Enemy goblin("Goblin"); // damage по умолчанию равен 10
Enemy dragon("Dragon", 50); // damage устанавливается в 50Как только вы определяете параметризованный конструктор, компилятор больше не генерирует конструктор по умолчанию автоматически.
Попробуйте сами
#include <iostream>
#include <iomanip>
#include <string>
#include "Product.h"
using namespace std;
int main() {
// Считать первый товар: название, цена и количество
string name1;
double price1;
int quantity1;
cin >> name1 >> price1 >> quantity1;
// Считать второй товар: название и цена
string name2;
double price2;
cin >> name2 >> price2;
// Считать третий товар: только название
string name3;
cin >> name3;
// TODO: Создать три объекта Product, используя соответствующий конструктор для каждого
// TODO: Вызвать display() для каждого товара
// TODO: Рассчитать и вывести общую стоимость инвентаря
// Формат: "Total inventory value: $<value>"
// Использовать fixed и setprecision(1) для одного десятичного знака
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Итоги — Обобщенный контейнер