Общее понятие о классах в С++
В данной публикации я бы хотел продолжить тему изучения языка программирования С++. И сегодня мы узнаем, что такое ООП, что это такое, зачем нужно и как с этим жить дальше! :)
И так, что же такое объектно ориентированное программирование? Давайте для начала узнаем, что об этом говорит Википедия:
Объектно-ориентированное программирование (ООП) — методология программирования, основанная на представлении программы в виде совокупности объектов, каждый из которых является экземпляром определённого класса, а классы образуют иерархию наследования.
Идеологически ООП — подход к программированию как к моделированию информационных объектов, решающий на новом уровне основную задачу структурного программирования: структурирование информации с точки зрения управляемости, что существенно улучшает управляемость самим процессом моделирования, что, в свою очередь, особенно важно при реализации крупных проектов.
Но если сказать проще, то до сих пор у нас программа представляла собой набор функций, каждая из которых выполняла свою строго определённую задачу. Но концепция ООП — предлагает немного другой подход. Когда мы разделяем задачу на объекты, каждый из которых решает некую отдельную задачу. Давайте я просто покажу всё на примере.
Давайте вспомним задачу из прошлого урока. Напомню, что там у нас была задача, где было множество рекламных мониторов, на которые мы рассылали рекламные сообщения. Были функции, которые получали строки из БД, затем мы рассылали эти строки в функции, которые печатали текст на мониторе. Вроди как всё хорошо, но почему бы не реализовать таким образом?
Ввесь функционал мы пишем в одном классе:
using namespace std;
class monitor{
public: // public - секция, тут храним переменные и методы, которые видны всем
monitor(string type){
this -> All = 4; // Делаем вид, что получили из базы значение, сколько мониторов используется
this -> type = type; // сохраняем информацию, где используется этот монитор
}bool PrintText(string text){
for (size_t i = 0; i < this -> All; i++){
cout << "Расположение монитора: " << this -> type << " №: " << i << "; Текст сообщения: " << text << ";" << endl;
}
return true; // Имитируем проверку, что сообщение было успешно отправлено
}private: // private - секция, тут храним переменные и методы класса, которые нужны для собственных целей
int All; // Сколько у нас всего мониторов
string type; // Тут храним тип, где используется этот монитор
};
И файл main.cpp
#include <string>
#include <iostream>
#include "monitor.cpp"using namespace std;
int main(){
setlocale(LC_ALL, "ru_RU.UTF-8");monitor shoop("магазин");
monitor street("улица");
monitor home("дом");if(shoop.PrintText("Сообщение для магазина"))
cout << "Сообщение для магазинов успешно разослано" << endl << endl;
else
cout << "Ошибка рассылки сообщения для магазинов" << endl << endl;if(street.PrintText("Сообщение для уличных стендов"))
cout << "Сообщение для улицы успешно разослано" << endl << endl;
else
cout << "Ошибка рассылки сообщения улицы" << endl << endl;if(home.PrintText("Сообщение для дома"))
cout << "Сообщение для дома успешно разослано" << endl << endl;
else
cout << "Ошибка рассылки для дома" << endl << endl;return 0;
}
И давайте сразу разберём файл monitor.cpp, что мы тут видим? Для начала мы видим новую конструкцию class, которая говорит, что мы хотим описать класс с именем monitor. Для упрощения понимания, вы можете представить себе класс как некий набор переменных и функций, который заключён «в обёртку», которая называется классом. Вся эта обёртка делится на две (чуть позже узнаем о третей) части. Это public: секция, которая у нас в начале и private:, которая чуть ниже. О том, зачем нужны эти поля — мы разберём чуть позже, после того, как разберёмся с конструктором и экземплярами класса.
Правда давайте сразу запомним, что если мы говорим о классе, то говорить «переменная» и «функция» — не верно. Правильно говорить «поля» и «методы». Так же в данном классе есть конструктор класса. Давайте с его и начнём.
И так, конструктор класса можно представить как функцию, которая вызывается в момент, когда мы в функции main() создаём объект класса (Т.е. когда мы в функции main() пишем monitor shoop("магазин");). В этот момент запускается конструктор monitor(string type).
Конструктор класса нужен для того, чтоб подготовить класс к работе. Если говорить о данной ситуации, то мы тут получаем поле с типом, где находиться наш монитор, а так же получаем из БД значение, сколько мониторов у нас есть в работе.
Обратите внимание, что в отличии от функции, где после окончания работы, данные пропадают и вы не можете обратиться к её данным заново, тут мы сохраняем данные о типе и количестве мониторов — и они остаются до момента, пока мы сами не удалим экземпляр класса!
Что такое экземпляр класса? В функции main() у нас есть три строки:
- monitor shoop("магазин");
- monitor street("улица");
- monitor home("дом");
Так вот, каждая из этих строк создаёт свой, отдельный экземпляр класса monitor. Т.е. у нас в данной программе есть один класс и три экземпляра класса.
И так, мы создали три экземпляра класса, что с ними можем делать? Как я уже говорил выше, в отличии от функции, они продолжают работать и мы можем к ним обратиться. Но как это сделать? Вот тут есть важный нюанс, о котором я упоминал выше. Помните о секциях public: и private:? Так вот, из функции main() мы можем обратиться к тем функциям методам, которые находятся в секции public:. Собственно они по этому так и называются. Публичная секция — для тех методов, к которым мы можем обращаться из вне, а закрытая — для тех полей, которые нам нужно хранить для «служебных целей».
К примеру, если бы у нас поле int All; было в общедоступной секции public: — вы могли бы по ошибке обратиться к ему и изменить значение таким образом: shoop.All = 6. Что бы тогда случилось? Вместо того, чтоб рассылать строку на 4 монитора в магазинах, программа начала бы рассылать на шесть. Но т.к. пятого и шестого в природе не существует — вы бы просто получили ошибку и долго разбирались, почему программа работает не верно. Чтоб избежать подобных ошибок — и было введено поле private:, которым вы сами себя оберегаете от подобных ошибок.
Для вывода сообщений мы добавили себе в общедоступную секцию public:, метод bool PrintText(string text). И данный метод уже занимается тем, чтоб рассылать сообщение на все мониторы, которые есть в списке, полученном в конструкторе класса. В качестве усложнения задачи, данный метод возвращает булево значение, которое имитирует ответ о успешном или не успешном завершении рассылки.
Вот и всё, что я хотел на сегодня рассказать. На самом деле это лишь вершина айсберга. Мы лишь узнали, что есть такая штука, как классы. В следующих публикациях мы продолжим разбираться с темой классов, узнаем где ещё можно их использовать узнаем не только о конструкторе, но и о деструкторе, наследовании и многих других фичах, которые очень пригодятся в работе!
А в качестве домашнего задания — попробуйте немного модифицировать класс таким образом, чтоб по окончании рассылки выводил информацию о том, сколько всего рассылок было сделано с момента создания экземпляра класса. Т.е. к примеру, если мы вызовем в main():
shoop.PrintText("Сообщение для магазина")
shoop.PrintText("Сообщение для магазина")
shoop.PrintText("Сообщение для магазина")
После трёх вызовов, он должен писать, что было сделано три рассылки. Сможете реализовать? Пишите свои варианты в комментариях!
Комментарий успешно отправлен. Он будет опубликован после проверки модератором.