Форум программистов, компьютерный форум CyberForum.ru

Парадигмы: императивная vs ООП - C++

Восстановить пароль Регистрация
 
 
PitMagnum
3 / 3 / 0
Регистрация: 28.05.2012
Сообщений: 16
19.12.2012, 00:08     Парадигмы: императивная vs ООП #1
Здравствуйте, форумчане. Меня мучает проблема, можно так сказать, эстетически-идеологического характера. Суть заключается в следующем:

Концепция разделения данных и управления данными ООП дает большие преимущества - по крайней мере если алгоритмы имеют сложную структуру, то классы не дают превратиться в кашу из данных и обработчиков этих данных, что может случиться, если использовать императивный стиль программирования. С другой стороны ООП заточен на представление всего и вся в виде объектов. И во многих случаях это естественно и правильно. Например при написании персонажей в игре. Поскольку персонаж - это без сомнения объект.

Но беда в том, что не всегда что-то стойко ассоциируется с объектом. Например у меня есть модуль, который грубо говоря содержит 3 основных функции: шифрование по ГОСТ 28147-89 в режиме простой замены, шифрование по ГОСТ 28147-89 в режиме гаммирования и хеш-функция по ГОСТ 34.11-94. Последние две функции используют первую для своих вычислений. Есть еще вспомогательные функции. А еще есть данные, которые кое как распиханы по функциям. И я явственно вижу, что применив ООП парадигму, я смогу улучшить этот модуль - сформируется четкий интерфейс, данные будут размещены в одном месте, а следовательно, не будет всего этого дрочерства с передачей кучи параметров от одной функции к другой.

С другой стороны я понимаю, что обрамив все в класс или несколько классов, я обречен на вызов этих функций сугубо через объекты, которые мне предварительно нужно создать перед использованием. Но это было бы так же глупо, как если бы я захотел вычислить синус и мне пришлось бы написать:

C++
1
2
Math mth;
x = mth.sin(y);
Нет стойкой ассоциации с объектом. Шифратор.вычислиХешФункцию("in god we trust"), Сортировщик.отсортируйМассив(arr) - все это как-то глупо и неестественно. Вот и спрашивается - как можно сделать элегантно - чтоб и данные с функциями не мешать, и чтоб потом как простые функции вызывать можно было? Есть, конечно, функторы, но объект все равно нужно где-то создать. Еще можно данные вынести в глобальную область - но мне всегда твердили, что глобальные переменные - это зло. Где истина?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.12.2012, 00:08     Парадигмы: императивная vs ООП
Посмотрите здесь:

ООП на С++ C++
ООП C++
C++ ООП C++
C++ ООП
C++ ООП
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Avazart
 Аватар для Avazart
6893 / 5133 / 250
Регистрация: 10.12.2010
Сообщений: 22,560
Записей в блоге: 17
19.12.2012, 00:33     Парадигмы: императивная vs ООП #2
C++
1
2
Math mth;
x = mth.sin(y);
Сделать соответствующие методы статическими в классе
C++
1
x = Math::sin(y);
Добавлено через 1 минуту
Цитата Сообщение от PitMagnum Посмотреть сообщение
конечно, функторы, но объект все равно нужно где-то создать.
Для функтуров зачем ?

Добавлено через 2 минуты
Цитата Сообщение от PitMagnum Посмотреть сообщение
Еще можно данные вынести в глобальную область - но мне всегда твердили, что глобальные переменные - это зло. Где истина?
Собственно зло... если данных много то тут без классов нормально не получится.

Главное в этом всю картину объять и понять что действительно нужно пользователю и как все сгруппировать.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.12.2012, 01:50     Парадигмы: императивная vs ООП #3
Цитата Сообщение от PitMagnum Посмотреть сообщение
Где истина?
Истина в том, что объект имеет состояние. Вычислятор синусов состояния не имеет, он всегда выдаёт один и тот же синус, поэтому вполне может быть просто функцией (чтоб не мешалась, можно засунуть в неймспейс).

С хеш-функцией то же самое. Если это вычислиМнеMD5(), то у неё нет состояния. Если же это объект "вычислитель хеш-функций", то у него есть состояние: текущий алгоритм, по которому он вычисляет хеш-функцию. Но его можно превратить в функцию, которая не имеет состояния, если она будет принимать этот алгоритм как аргумент. Соответственно, можно и наоборот: сделать объект, который будет хранить это состояние у себя, а его метод будет подсовывать это состояние stateless-функции.
nshell32gmail
5 / 5 / 1
Регистрация: 26.11.2012
Сообщений: 19
19.12.2012, 02:11     Парадигмы: императивная vs ООП #4
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Истина в том, что объект имеет состояние. Вычислятор синусов состояния не имеет, он всегда выдаёт один и тот же синус, поэтому вполне может быть просто функцией (чтоб не мешалась, можно засунуть в неймспейс).

С хеш-функцией то же самое. Если это вычислиМнеMD5(), то у неё нет состояния. Если же это объект "вычислитель хеш-функций", то у него есть состояние: текущий алгоритм, по которому он вычисляет хеш-функцию. Но его можно превратить в функцию, которая не имеет состояния, если она будет принимать этот алгоритм как аргумент. Соответственно, можно и наоборот: сделать объект, который будет хранить это состояние у себя, а его метод будет подсовывать это состояние stateless-функции.
Статические методы И статическая переменная, хранящая состояние, не?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.12.2012, 02:30     Парадигмы: императивная vs ООП #5
А если потребуется несколько состояний одновременно хранить?
0x10
19.12.2012, 03:38
  #6

Не по теме:

Императивная парадигма является противоположностью декларативной, но не объектной.

PitMagnum
3 / 3 / 0
Регистрация: 28.05.2012
Сообщений: 16
19.12.2012, 07:27  [ТС]     Парадигмы: императивная vs ООП #7
Блин, а про статические методы я и не подумал совсем.. спасибо, такая концепция меня вполне устраивает.

Для функтуров зачем ?
ну дык..

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>
#include <string>
 
class SimpleFunctor {
    std::string name_;
public:
    SimpleFunctor(const char *name) : name_(name) {}
    void operator()() { std::cout << "Oh, hello, " << name_ << endl; }
};
 
int main() {
    SimpleFunctor sf("catonmat");
    sf();  // выводит "Oh, hello, catonmat"
}
сначала создаем объект, потом пользуемся как функцией.. или вы не об этом?

Императивная парадигма является противоположностью декларативной, но не объектной
я с этим абсолютно согласен, это я в данном контексте поставил vs в заголовке, и то это не совсем корректно, конечно.

~OhMyGodSoLong~, а разве несколько состояний нельзя хранить нельзя хранить в нескольких статических переменных? Ну, естественно, если это две разные категории состояния. Если нужно хранить несколько состояний одной категории, то если я все правильно понял, это возможно только при двух объектах с разными состояниями. Но здесь-то и противоречий в таком случае не возникает - объект сам собой напрашивается.

Меня еще один вопрос интересует - операторы cin и cout являются по сути классовыми объектами. А где они создаются?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.12.2012, 09:11     Парадигмы: императивная vs ООП #8
Цитата Сообщение от PitMagnum Посмотреть сообщение
Меня еще один вопрос интересует - операторы cin и cout являются по сути классовыми объектами. А где они создаются?
Это глобальные константы. Как и все остальные глобальные объекты, они инициализируются в начале выполнения программы перед выполнением кода main().
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
19.12.2012, 15:37     Парадигмы: императивная vs ООП #9
Цитата Сообщение от PitMagnum Посмотреть сообщение
операторы cin и cout
Это не операторы, а объекты классов std::istream и std::ostream.

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Это глобальные константы.
С чего это они константы?
C++
1
extern istream cin;
Герц
523 / 340 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
19.12.2012, 15:45     Парадигмы: императивная vs ООП #10
Попробуй измени их)
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.12.2012, 15:49     Парадигмы: императивная vs ООП #11
Цитата Сообщение от Toshkarik Посмотреть сообщение
С чего это они константы?
В смысле неизменяемости привязок имён std::cin и std::cout к объектам, а не неизменяемости состояний этих объектов. Состояния этих объектов стандартных потоков можно изменять, но так как для них не определёно присваивание, то cout нельзя заставить выводить информацию куда-то в другое место.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.12.2012, 15:53     Парадигмы: императивная vs ООП #12
ОО - часть императивной: императивное программирование - это написание текстов, указывающих, что, как и с чем надо сделать, но не что в результате получить, а ООП - это написание текстов, указывающих, что, как и с чем надо сделать + декомпозиция задачи на основе типов данных + объединение подпрограмм с типами данных, ими обрабатываемыми + объединение свойств целого в единую сущность. По самой ОО из этого следует, что ОО - прямой потомок императивной парадигмы.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
19.12.2012, 16:01     Парадигмы: императивная vs ООП #13
Герц, Пожалуйста:
C++
1
cout.fill( '0' );
Добавлено через 2 минуты
Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
cout нельзя заставить выводить информацию куда-то в другое место
В любой книге сказано, что по умолчанию cout привязан с монитору, и что это можно изменить. Так же как и cin привязан к клавиатуре, и это тоже можно изменить.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.12.2012, 16:12     Парадигмы: императивная vs ООП #14
Цитата Сообщение от Toshkarik Посмотреть сообщение
В любой книге сказано, что по умолчанию cout привязан с монитору, и что это можно изменить. Так же как и cin привязан к клавиатуре, и это тоже можно изменить.
Продемонстрируйте, пожалуйста, на примере:
C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <fstream>
 
int main()
{
    std::fstream file("foo", std::fstream::out);
    /* впишите сюда ваш код */
    std::cout << "Bar";
}
// после выполнения в файле foo находится строка "Bar"
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
19.12.2012, 16:21     Парадигмы: императивная vs ООП #15
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <iostream>
#include <fstream>
 
 
int main() {
   std::fstream file( "out.txt", std::ios::out );
   std::streambuf *bck = std::cout.rdbuf();
    
   std::cout << "Terminal" << std::endl;
 
   std::cout.rdbuf( file.rdbuf());
   
   std::cout << "File" << std::endl;
 
   std::cout.rdbuf( bck );
 
   std::cout << "Terminal 2" << std::endl;
   
   return 0;
}
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.12.2012, 16:24     Парадигмы: императивная vs ООП #16
А как зовут поток принтера?
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
19.12.2012, 16:37     Парадигмы: императивная vs ООП #17
Toshkarik, спасибо за исправление. Никогда особо не дружил с плюсовыми потоками :(

Цитата Сообщение от taras atavin Посмотреть сообщение
А как зовут поток принтера?
Эээ... Файл с именем LPT1, PRN или там /dev/pr0? Боюсь, это всё же ОС-специфичная вещь.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.12.2012, 16:45     Парадигмы: императивная vs ООП #18
Виндузячий дефолтный принтер.
Toshkarik
 Аватар для Toshkarik
1139 / 856 / 50
Регистрация: 03.08.2011
Сообщений: 2,381
Завершенные тесты: 1
19.12.2012, 16:54     Парадигмы: императивная vs ООП #19
Цитата Сообщение от taras atavin Посмотреть сообщение
А как зовут поток принтера?
Что тут имеется ввиду под "принтером", и какого рода должно быть название?

Цитата Сообщение от ~OhMyGodSoLong~ Посмотреть сообщение
Никогда особо не дружил с плюсовыми потоками
По большому счету, они мало чем отличаются, основное отличие это, как раз, в объектах класса streambuf и объектах классах производных от него ( filebuf в файловых потоках и stringbuf в строковых потоках ).

Добавлено через 3 минуты
taras atavin, если имеется ввиду физическое устройство принтер, для распечатки текста на бумаге, это это, как и сказал ~OhMyGodSoLong~, платформозависимое API. В самом C++ ничего нет для работы с принтером.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2012, 16:54     Парадигмы: императивная vs ООП
Еще ссылки по теме:

ООП C++
C++ ООП
C++ Парадигмы программирования

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.12.2012, 16:54     Парадигмы: императивная vs ООП #20
Цитата Сообщение от Toshkarik Посмотреть сообщение
и какого рода должно быть название?
Идентификатор конечно. Что же ещё?
Yandex
Объявления
19.12.2012, 16:54     Парадигмы: императивная vs ООП
Ответ Создать тему
Опции темы

Текущее время: 08:59. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru