- •Классы, Объекты и Методы
- •Struct DateStruct {
- •Int month;
- •Int year;
- •Методы классов
- •Void print () {
- •Int main () {
- •Int main () {
- •Int main () {
- •Спецификаторы доступа public и private
- •Int year; // открыто по умолчанию
- •Int main () {
- •Int main () {
- •Int main ()
- •Структуры. Классы
- •Инкапсуляция, Геттеры и Сеттеры Инкапсуляция
- •Int m_array[10];
- •Int main () {
- •IntArray array;
- •Void setValue(int index, int value) {
- •Функции доступа (геттеры и сеттеры)
- •Int m_month;
- •Int m_year;
- •Int main () {
- •Краткий обзор l-value и r-value
- •Инициализация ссылок
- •Ссылки в качестве параметров в функциях
- •Void changeN (int &ref) {
- •Int main () {
- •Int value1;
- •Int otherValue;
- •Ссылки. Указатели
- •Конструкторы
- •Int main () {
- •Конструкторы по умолчанию
- •Конструкторы с параметрами
- •Int m_numerator;
- •Int m_denominator;
- •Int getNumerator () {return m_numerator; }
- •Int getDenominator () {return m_denominator; }
- •Копирующая инициализация
- •Уменьшение количества конструкторов
- •Неявно генерируемый конструктор по умолчанию
- •Int main () {
- •Int main () {
- •Классы, содержащие другие классы
- •Int main() {
- •Список инициализации членов класса
- •Списки инициализации членов класса
- •Int m_value1;
- •Values() {
- •Int m_value1;
- •Инициализация массивов в классе
- •Инициализация переменных-членов, которые являются классами
- •Int main() {
- •Использование списков инициализации
- •Int m_value1;
- •Int m_value1;
- •Int m_value1;
- •Порядок выполнения в списке инициализации
- •Инициализация нестатических членов класса
- •Void print() {
- •Int main() {
- •Void print() {
- •Int main() {
- •Void print() {
- •Int main() {
- •Void print() {
- •Int main() {
- •Делегирующие конструкторы
- •Void DoX() {
- •Init();
- •Init();
- •Void Init()
- •Int main() {
- •Ещё о делегирующих конструкторах
- •Деструкторы
- •Имена деструкторов
- •Пример использования деструктора на практике
- •Выполнение конструкторов и деструкторов
- •Int getId() { return m_nId; }
- •Int main() {
- •Предупреждение о функции exit()
- •Скрытый указатель this
- •Скрытый указатель *this
- •Int m_number;
- •Int getNumber() { return m_number; }
- •Int main() {
- •Указатель this всегда указывает на текущий объект. Явное указание указателя this
- •Int data;
- •Цепочки методов класса
- •Заключение
Int main () {
Date date; // вызов неявного конструктора
return 0;
}
Вышеприведенный код скомпилируется, поскольку в объекте date сработает неявный конструктор (который является открытым).
Если ваш класс имеет другие конструкторы, то неявно генерируемый конструктор создаваться не будет. Например:
class Date {
private:
int m_day = 12;
int m_month = 1;
int m_year = 2018;
public:
Date (int day, int month, int year) // обычный конструктор (не по //умолчанию)
{ m_day = day;
m_month = month;
m_year = year;
}
// Неявный конструктор не создастся, так как мы уже определили свой //конструктор
};
Int main () {
Date date; // ошибка: Невозможно создать объект, так как конструктор //по умолчанию не существует, и компилятор не сгенерировал неявный //конструктор автоматически
Date today(14, 10, 2020); // инициализируем объект today
return 0;
}
Рекомендуется всегда создавать по крайней мере один конструктор в классе.
Это позволит вам контролировать процесс создания объектов вашего класса, и предотвратит возникновение потенциальных проблем после добавления других конструкторов.
Правило: Создавайте хотя бы один конструктор в классе, даже если это пустой конструктор по умолчанию.
Классы, содержащие другие классы
Одни классы могут содержать другие классы в качестве переменных-членов.
По умолчанию, при создании внешнего класса, для переменных-членов будут вызываться конструкторы по умолчанию. Это произойдет до того, как тело конструктора выполнится.
Это можно продемонстрировать следующим образом:
#include <iostream>
class A {
public:
A() { std::cout << "A\n"; }
};
class B {
private:
A m_a; // B содержит A, как переменную-член
public:
B() { std::cout << "B\n"; }
};
Int main() {
B b;
return 0;
}
Результат выполнения программы:
A
B
При создании переменной b вызывается конструктор B().
Прежде чем тело конструктора выполнится, m_a инициализируется, вызывая конструктор по умолчанию класса A.
Таким образом выведется A.
Затем управление возвратится обратно к конструктору B(), и тело конструктора B() начнет свое выполнение.
Здесь есть смысл, так как конструктор B() может захотеть использовать переменную m_a, поэтому сначала нужно инициализировать m_a !
Задание 1
a) Напишите класс Ball, который должен иметь следующие две закрытые переменные-члены со значениями по умолчанию:
m_color (Red); m_radius (20.0).
В классе Ball должны быть следующие конструкторы:
для установления значения только для m_color;
для установления значения только для m_radius;
для установления значений и для m_radius, и для m_color;
для установления значений, когда значения не предоставлены вообще.
Не используйте параметры по умолчанию для конструкторов. Напишите еще одну функцию для вывода цвета (m_color) и радиуса (m_radius) шара (объекта класса Ball).
Следующий код функции main ():
int main () {
Ball def;
def.print();
Ball black("black");
black.print();
Ball thirty(30.0);
thirty.print();
Ball blackThirty("black", 30.0);
blackThirty.print();
return 0;
}
Должен выдавать следующий результат:
color: red, radius: 20
color: black, radius: 20
color: red, radius: 30
color: black, radius: 30
b) Теперь обновите ваш код из предыдущего задания с использованием конструкторов с параметрами по умолчанию. Постарайтесь использовать как можно меньше конструкторов.
Задание №2
Что произойдет, если не объявить конструктор по умолчанию?
