![]() |
C++ и ООП фича для чуть более продвинутых новичков
Пожалуй на форуме не хватает топика про преимущества ООП. Нада бы исправить сей недостаток. А то многовато мнений, что с++ мощный язык, но при этом используют его ровно так же, как и си и паскаль. Я опишу интересный прием программирования с использованием ООП, который пригодился мне. Если еще что нить интересное вспомню и будет интерес - продолжу тему.
Итак, начнем. Наверняка вы сталкивались с ситуациями, когда необходимо освобождать ресурсы. Например файлы, память, сокеты, етц етц етц. Все просто, когда в начале функции открыли файл, в конце закрыли. Но как только линейность использования ресурсов нарушается или появляются зависимости - начинаются проблемы. Вторая проблема - не забыть закрыть файл в конце большой функции. Типичный пример первой проблемы - использование маппингов файлов. Обычно код выглядит примерно так: Код:
bool ReadData (char* File, char* buffer)Ну а теперь перейдем к решению. Итак, первым делом создаем 3 класса - KFile для файла, KMapping для маппинга и KViewOfFile для проекции файла в память. Код:
#include <iostream>Суть приема. А потому, что мы объявили объекты классов локально. Это значит, что при выходе из функции они будут уничтожены. Уничтожение объекта приводит к вызову его деструктора. Всю логику контроля хэндлов мы как раз там и реализовали. В итоге все работает и без нашего вмешательства. В данном примере есть только одно опасное место(не считая конструктора копирования, который лучше бы сделать приватным. Или решив проблему как то иначе. В чем суть проблемы - попробуйте понять сами, зная лишь что конструктор копирования просто копирует значение полей в новый объект) - в данном случае критичен порядок определения переменных наших классов, т.к. уничтожаются они в обратном порядке относительно создания. А для нас это вполне важно. Нужно сначала делать унмап, потом закрывать маппинг и только потом закрывать хэндл файла. Это на самом деле очень плохо, т.к. заставляет нас помнить об этой фиче. Но для удобства мы можем поступить просто - сделать еще один класс, который сокроет(инкапсулирует) все шаги открытия маппинга до одной операции - open. Например так: Код:
class KFileMapping{Код:
void test2()1) Защита от ошибок 2) Упрощение кодирования 3) Повторное использование кода. Постепенно со временем вы соберете подборку своих классов, реализующих наиболее нужный вам функционал, с нужными вам интерфейсами(например не часто приходится указывать, как открывать файл - только для чтения, только для записи, итп. Вы делаете так, чтобы этим было максимально удобно пользоваться. Когда понадобится указывать доступ - просто добавите новый метод, минимально трогая старую реализацию). Ну вот собсно и все. PS: то, что мы с вами сделали, это по сути паттерн RAII (велкам ту вики), только немного модифицированный(в идеале метод open нада заменить вызовом конструктора, но по мне итак вполне юзабельно) |
Хороший обзоз, пример паттерна + многократное использование кода )
Вот только жаль что все чаще и чаще встречаешь с++ код подобный первому примеру, в натив си, еще такой подход приемлен, но не в плюсах ) |
тут важно понять, что нужно всегда учитывать требования к задаче, вероятность доработки программы и прочее. Один разок записать/прочитать один файл - можно и процедурным программированием обойтись, также как не стоит перегружать оператор сложения для собственных классов, чтобы сложить два числа.
А вообще в продвинутых(читать высокоуровневых) платформах реализованы Garbage Collector'ы, которые автоматически подчищают все объекты и прочее. |
Цитата:
|
Цитата:
|
| Время: 07:48 |