Форум программистов, компьютерный форум, киберфорум
ООП и паттерны
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  
 
 
Рейтинг 5.00/34: Рейтинг темы: голосов - 34, средняя оценка - 5.00
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,223
Записей в блоге: 2

Учебный пример ООП

13.09.2016, 11:26. Показов 9333. Ответов 123
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Добрый день

Знакомство ООП часто начинается с этого примера. Ну не "строчка в строчку" (это я взял первый попавшийся в гугле), но те же классы и методы.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// Базовый класс Фигура
// для него заданы методы, реализация которых
// отложена для выведенных классов
 
class Shape
{
public:
// Внешняя часть класса
    virtual bool Draw() = 0; // Перерисовать фигуру
    virtual bool Move(double _x, double _y) = 0; // Сдвинуть фигуру
    virtual bool Zoom(double scale) = 0; // Масштабировать
 
protected:
    // Защищенная часть класса, доступная только
    // выведенным из него классам
 
    double coordX; // Атрибут - координата X
    double coordY; // Атрибут - координата Y
};
 
// Класс Круг выведенный из класса Фигура
class Circle : public Shape
{
public:
    virtual bool Draw() {...}; // Реализация перерисовки
    virtual bool Move(double _x, double _y) {...}; // Реализация сдвига
    virtual bool Zoom(double scale) {...}; // Реализация операции масштабирования
 
private:
    // Внутренняя часть доступная только самому классу
    double radius; // Атрибут - длина радиуса
};
 
// Класс Квадрат выведенный из класса Фигура
class Square : public Shape
{
 
public:
    virtual bool Draw() {...}; // Реализация перерисовки
    virtual bool Move(double _x, double _y) {...}; // Реализация сдвига
    virtual bool Zoom(double scale) {...}; // Реализация операции масштабирования
 
private:
    // Внутренняя часть доступная только самому классу
    double side; // Атрибут - длина стороны квадрата
};
После первого знакомства прошло несколько лет (а для кого и много лет), теперь Вы обладаете гораздо большим опытом. Как изменилось Ваше отношение к этому примеру? Что в нем наивно (или просто плохо), а что остается верным и правильным?

С уважением
Игорь
0
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
13.09.2016, 11:26
Ответы с готовыми решениями:

Неизвестные переменные в сценарии(учебный пример)
Учебный сценарий l> <head> <title>Котировка акций от NASDAQ</title> </head> <body> <?php // Выбор обозначения...

Учебный пример реализации веб приложения или сайта
Нужен учебный(полноценно-рабочий) пример реализации веб приложения или сайта. Родные Erlang и OTP, а не Elixir.

Не работает учебный пример с БД: "произошла ошибка, связанная с сетью или с определенным экземпляром"
Начал писать учебный пример с msdn http://msdn.microsoft.com/ru-ru/library/bb386940.aspx написал тренировочный код: using System; ...

123
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
18.09.2016, 22:47
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Для примера их превосходства распараллельте мне плиз уточнение изолированного
Для примера превосходства огнестрельного оружия над холодным нарежьте мне плиз колбасу пистолетом.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Второе полный идиотизм ведущий к очень высокому росту как потребной памяти так и вычислений.
Вы неправы.
C#
1
2
3
4
5
double MyFunc(double a, double b)
{
    double x = a * b + 5;
    return x * x; 
}
Каким образом неизменяемость x приводит "к очень высокому росту как потребной памяти так и вычислений"?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А насчет независимости то вы ошибаетесь,неопределенность фактического типа АДТ при возможности многократного присваивания ведет к комбинаторному взрыву при генерации кода.
Это Вы ошибаетесь. Можете, например, взглянуть на F#. Там есть изменяемые переменные и АТД - и никакого комбинаторного взрыва. Насчёт неопределённости фактического типа АДТ Вы тоже ошибаетесь. Сама переменная содержит эту информацию. И когда очередная инструкция зависит от этого, компилятор всегда может использовать таблицу переходов (обычный switch, если хотите).

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
В любом случае будут созданы все нужные варианты.
Я в коде написал три строчки (по одной на каждый "подвид"). А компилятор добавит таблицу переходов, содержащую переходы на эти три строчки. И всё это внутри одной единственной функции.
И сравните это с другим вариантом, где я написал одну строчку кода, а компилятор создаст по отдельной функции для каждого типа, для которого в коде встретится вызов этой обобщённой функции. В данном случае будет два: вариант для int и для double, которые будут использовать разные операторы сложения.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
18.09.2016, 23:21
Цитата Сообщение от Shamil1 Посмотреть сообщение
Каким образом неизменяемость x приводит "к очень высокому росту как потребной памяти так и вычислений"?
А теперь тоже самое только в цикле.

Добавлено через 5 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Сама переменная содержит эту информацию. И когда очередная инструкция зависит от этого, компилятор всегда может использовать таблицу переходов (обычный switch, если хотите).
Ну вот это и есть римские цифры в вычислениях. Их развитие привело во первых к индирект переходам в таких случаях, а во вторых к выводу о том что динамическая типизация нужна крайне редко, при этом статическая гораздо эффективней.

Добавлено через 4 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Для примера превосходства огнестрельного оружия над холодным нарежьте мне плиз колбасу пистолетом.
Т.е. без империтивщины и состояний даже корень извлечь невозможно. Что и требовалось доказать.

Добавлено через 4 минуты
Хотя суть именно этого примера была в другом - метод в принципе не параллелится. Хоть функционально хоть импиритивно хоть с изменяемыми состояниями хоть с неизменяемыми. Т.е. вывод прост - параллелятся или нет вычисления зависит от характера вычислений а не от неизменяемости переменных. При этом подавляющее большинство вычислений именно интегрирование дифуров по той или иной конечно-разностной схеме (т.е. следующий шаг вычислений требует результатов предыдущего что не праллелится в принципе )
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
19.09.2016, 00:41
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А теперь тоже самое только в цикле.
Нет. Вы писали, что "второе полный идиотизм ведущий к очень высокому росту как потребной памяти так и вычислений". Покажите мне, как это происходит в данном конкретном случае.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Их развитие привело во первых к индирект переходам в таких случаях
Поясните, что Вы имеете ввиду.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
а во вторых к выводу о том что динамическая типизация нужна крайне редко, при этом статическая гораздо эффективней
Причём тут динамическая типизация? АТД используются и в языках со статической типизацией.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Т.е. без империтивщины и состояний даже корень извлечь невозможно. Что и требовалось доказать.
Ваша логика хромает на обе ноги.
Сначала Вы просите показать преимущества неизменяемых переменных на придуманном Вами примере. То есть, из моей фразы "неизменяемость имеет свои преимущества" Вы сделали вывод, что эти преимущества проявляются на любом примере?
Потом из того, что я указал Вам на Вашу ошибку в логике, Вы сделали вывод, что "без империтивщины и состояний даже корень извлечь невозможно".
Вы, действительно, так думаете или просто тролите?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Хотя суть именно этого примера была в другом - метод в принципе не параллелится.
Если Вы считаете, что преимущества неизменяемых переменных проявляются только при распараллеливании, то Вы ошибаетесь.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
19.09.2016, 00:56
Цитата Сообщение от Shamil1 Посмотреть сообщение
Если Вы считаете, что преимущества неизменяемых переменных проявляются только при распараллеливании, то Вы ошибаетесь.
А ни в чем другом преимущества не может быть в принципе.

Добавлено через 2 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Потом из того, что я указал Вам на Вашу ошибку в логике, Вы сделали вывод, что "без империтивщины и состояний даже корень извлечь невозможно".
Ну вы же говорите что реализовать метод Ньютона средствам ФП так же сложно как резать колбасу пистолетом. А корень он знаете ли методом Ньютона извлекается. Для этого метод и разрабатывался. Т.е. получается программировать средствами ФП настолько же удобно и продуктивно, насколько резать колбасу пистолетом.

Добавлено через 6 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Поясните, что Вы имеете ввиду.
C++
1
2
3
4
5
6
7
8
9
10
11
void Do(DynamicType a){
    switch (a.type){
             case T1: Do_T1(a);
                         break;
             case T2: Do_T2(a);
                         break;
             ...
            case TN: Do_TN(a);
            default: ShowError();
    }
};
И неэффективно и непродуктивно. Неэффективно потому как адрес перехода вычисляется каждый раз на основе данных из инстанса, при этом для каждого из типов является константой. Гораздо эффективней вычислить адрес перехода при компиляции и записать в инстанс. При этом появляется возможность проверить наличие ошибки на этапе компиляции а не во время исполнения. Соответсвенно гораздо эффективнее и продуктивние заменить все это набором полиморфных типов с виртуальными методами.

Добавлено через 5 минут
При этом какая то часть возможных действий с с группой типов одинакова для всех членов группы независимо от а.type. Эти действия выделяются в невиртуальные методы и диспетчеризируются статически.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
19.09.2016, 01:22
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А ни в чем другом преимущества не может быть в принципе.
Вы ошибаетесь.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну вы же говорите что реализовать метод Ньютона средствам ФП так же сложно как резать колбасу пистолетом.
Я такого не говорил. Я вообще ничего не говорил на тему, сложно ли решить эту задачу, используя ФП.

Добавлено через 24 минуты
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
И неэффективно и непродуктивно.
Вы про код на С++?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Неэффективно потому как адрес перехода вычисляется каждый раз на основе данных из инстанса, при этом для каждого из типов является константой.
Про какое вычисление адреса перехода Вы говорите? Загружаем значение поля из берём адрес по этому индексу из массива. Дальше безусловный переход.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
При этом появляется возможность проверить наличие ошибки на этапе компиляции а не во время исполнения.
Я Вам уже раза три писал, что АТД не исключает статическую типизацию. Почти все функциональные языки - со статической типизацией. Например, в F# "default: ShowError();" вообще не нужен. Программа не скомпилируется, если какой-нибудь вариант будет отсутствовать.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
19.09.2016, 06:30
Цитата Сообщение от Shamil1 Посмотреть сообщение
Загружаем значение поля из берём адрес по этому индексу из массива. Дальше безусловный переход.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вы про код на С++?
Я про вот это:
Цитата Сообщение от Shamil1 Посмотреть сообщение
И когда очередная инструкция зависит от этого, компилятор всегда может использовать таблицу переходов (обычный switch, если хотите).
Цитата Сообщение от Shamil1 Посмотреть сообщение
Поясните, что Вы имеете ввиду.
Адрес перехода считается на этапе компиляции и записывается в таблицу. При вызове вместо свичей и т.п. адрес берется из таблицы и по нем происходит вызов.

Добавлено через 4 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вы ошибаетесь.
Та нет. Если не нужно их изменять можно их не изменять даже если возможность изменять значения имеется. А вот если нужно изменить и нельзя получается пляска с бубном и прочие черт знает что называемые тюринговской трясиной.

Добавлено через 2 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Я Вам уже раза три писал, что АТД не исключает статическую типизацию. Почти все функциональные языки - со статической типизацией. Например, в F# "default: ShowError();" вообще не нужен. Программа не скомпилируется, если какой-нибудь вариант будет отсутствовать.
Статическая типизация это задание типа на этапе компиляции а не в рантайме. При задании типа на этапе компиляции никакие дополнительные ид типа в инстансе не нужны.

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

Добавлено через 1 час 25 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вы неправы.
Ну давайте тгда на примере хеллоуверда чуток посложнее.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Каким образом неизменяемость x приводит "к очень высокому росту как потребной памяти так и вычислений"?
К примеру решение системы линейных уравнений методом Гаусса. Сколько копий матрицы необходимо сгенерить для решения системы если нельзя изменять значения элементов матрицы?

Добавлено через 10 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Неизменяемые переменные имеют много преимуществ по сравнению с изменяемыми.
Это заблуждение тех времен когда ОЗУ на лампах было слишком ненадежным а ОЗУ на ртутных линиях задержки слишком дорогим и потому маленьким. Кому то показалась привлекательной идея сваповать на перфоленту (вот откуда слухи про супернадежность хаскеля - перфолента надежнее чем ламповая ОЗУ). Только вот неясно было останется ли при этом вычислитель универсальныйм. Пока накрутив кучу логических высеров таки доказали что останется но с кучей неудобств, в массу пошли ЭВМ на транзисторах и накопители на магнитной ленте. Но желающим мозги потрахать как всегда неймется. К одному высеру прикрутили еще несколько и типа оно теперь вообще универсальное. Тогда возникает 2 вопроса: если неизменяемые переменные круче изменяемых зачем хаскелю нужны монады? И второй вопрос - если хаскель настолько крут, то почему за всю его 30 летнюю историю на нем не написано ни одной промышленной программы, а по сведениям из некоторых источников все попытки создать на хаскеле файловый менеджер заканчивались неизменно созданием фэйлового менеджера?
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,223
Записей в блоге: 2
19.09.2016, 06:39  [ТС]
Цитата Сообщение от EVP Посмотреть сообщение
Увеличив косвенность вдвое, скорость падает ещё в два раза,
Скорость какая(или чего)? Доступа к методу делающему содержательную часть (вычисления)? Это никого не волнует пока не станет соразмеримым с самими вычислениями. Упрощенно

расчеты - 95%
накладные - 5% (в лучшем случае)

И вот Вы упорно доказываете как можно ужать 5% - а толку? 95%-то останется. Не надо так злоупотреблять горячительным (std)

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
void Do(DynamicType a){
switch (a.type){
case T1: Do_T1(a);
break;
case T2: Do_T2(a);
break;
...
case TN: Do_TN(a);
default: ShowError();
}
};

И неэффективно и непродуктивно. Неэффективно потому как адрес перехода вычисляется каждый раз...
Все-таки "просто так" передавать структуры по значению не стоит. Быть экспертом выжимающим скорость "до упора" конечно приятно, но такой подход - (поза)вчерашний день. Слишком мал здесь куш/выигрыш чтобы ради него усложнять код, гораздо лучше посвятить это время эффективному распараллеливанию и, особенно в последнее время, как задействовать GPU.
0
19.09.2016, 13:06

Не по теме:

Цитата Сообщение от Igor3D Посмотреть сообщение
расчеты - 95%
накладные - 5% (в лучшем случае)
И вот Вы упорно доказываете как можно ужать 5% - а толку? 95%-то останется.
Цитата Сообщение от EVP Посмотреть сообщение
Так, например, переделка кода с Java на C++
без изменения алгоритмов проводит к увеличению скорости до 20 раз
Кликните здесь для просмотра всего текста
Встречаются два одноклассника. Новыи русский, и простой советский инженер.
- Вась, это ты? На 600-том мерсе, в красном пиджаке? Ведь в школе у тебя всегда были одни двоики. По математике у тебя дважды два всегда пяти равнялось. О квадратном корне ты вообще никогда не слыхал! Я - школу с медалю, институт с красным дипломом (смотрит на свое пальто) - полная ерунда...
- Ты понимаешь, Санек. Все очень просто. Еду в Германию и покупаю бочку пива за 1000 баксов. Приезжаю домой, толкаю ее за 3000 баксов. Вот на эти два ПРОЦЕНТА я и живу.

:)
Есть интуиция, которая проверяется профилировщиком.
Что простыми оптимизациями не устраняется, устраняется изменениями алгоритмов,
но это всё от конкретной программы зависит.
Разумеется программы разные и одни и те же рецепты оптимизаций окажут разный эффект.
На этот случай есть профилировщик и программист.
Цитата Сообщение от EVP Посмотреть сообщение
Не призываю выкидывать виртуальность
ЗЫ: Это всё, что хотел сказать по этим вопросам.

0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
19.09.2016, 16:42
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Адрес перехода считается на этапе компиляции и записывается в таблицу. При вызове вместо свичей и т.п. адрес берется из таблицы и по нем происходит вызов.
Не понял разницы. Компилятор, когда возможно, оптимизирует switch таблицей переходов. В данном случае это возможно. То есть, сопоставление по образцу в приведённом мной коде делается через таблицу переходов (jumps tabel).

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Если не нужно их изменять можно их не изменять даже если возможность изменять значения имеется. А вот если нужно изменить и нельзя получается пляска с бубном и прочие черт знает что называемые тюринговской трясиной.
Если их нельзя изменять, то упрощается отладка/чтение кода программистом и компилятор имеет больше возможностей для оптимизации. А вот если нужно изменять, то... Вы ни за что не догадаетесь... то нужно использовать другой вид переменных - те, которые можно изменять. Вроде, так просто... неужели не очевидно?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Ну давайте тгда на примере хеллоуверда чуток посложнее.
Для начала замените "всегда" в своём утверждении на "иногда" ("использование неизменяемых переменных иногда приводит к росту как потребной памяти так и вычислений"). А до тех пор я буду выбирать тот пример, который мне больше всего подходит.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Это заблуждение тех времен когда ОЗУ на лампах было слишком ненадежным
Зачем в С++ добавили возможность объявлять аргументы функции и методы класса const? Тоже не даёт никаких преимуществ и объясняется какой-нибудь занимательной историей с перфокартами?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Статическая типизация это задание типа на этапе компиляции а не в рантайме. При задании типа на этапе компиляции никакие дополнительные ид типа в инстансе не нужны.
В Haskell и F# тип задаётся на этапе компиляции. Никакие дополнительные ид типа в инстансе не нужны.
Так в приведённом мной примере тип Shape, и компилятор это знает без всяких ид. Надеюсь, Вы не путаете автоматический вывод типов с динамической типизацией?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А корень он знаете ли методом Ньютона извлекается. Для этого метод и разрабатывался.
Вы предлагаете мне показать преимущество использования неизменяемых переменных на примере кода, который вообще не использует никаких переменных...
C#
1
2
double Sqrt(double x, double accuracy, double guess = 1.0) 
    => Math.Abs(x - guess*guess)/x < accuracy ? guess : Sqrt(x, accuracy, (guess + x/guess)/2);
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,223
Записей в блоге: 2
20.09.2016, 09:12  [ТС]
Переменные изменяемые и нет, отложенные вычисления, изумительно компактный синтаксис и.т.п. - все это конечно хорошо, но это подробности языка. Это не концепции. Хорошо или плохо но стартовый пример весьма конкретно учит что надо делать. В грубо-примитивной форме

- не держи данные открытыми (рисуй геттеры/сеттеры)
- выделяй базовые классы и наследуйся чтобы потом не переписывать одно и то же
- заряжай виртуалы

И миллионы людей делают именно это - с различным успехом. Что это не решает всех проблем и всегда найдется масса исключений - очевидно. Но вот скажите - а что взамен? Хорошо, допустим критики правы и ООП отжило свое. Как тогда я должен программировать? Каких принципов придерживаться, к чему стремиться? Где это сформулировано? (хоть как-то, о таком примере как стартовый я и не мечтаю).
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
20.09.2016, 19:02
Цитата Сообщение от Igor3D Посмотреть сообщение
Переменные изменяемые и нет, отложенные вычисления, изумительно компактный синтаксис и.т.п. - все это конечно хорошо, но это подробности языка. Это не концепции.
Переменные - это не только подробности языка. От того, какого вида переменные присутствуют в языке, зависит, какие вычислительные модели он поддерживает, какие приёмы программирования можно применять и какие шаблоны проектирования удобно использовать.
Например, в С++ нельзя связывать переменные. (Есть только присваивание - связывание переменной и значения). А в некоторый языках, например, записи A=B и B=A эквивалентны.

Цитата Сообщение от Igor3D Посмотреть сообщение
Хорошо, допустим критики правы и ООП отжило свое. Как тогда я должен программировать? Каких принципов придерживаться, к чему стремиться? Где это сформулировано? (хоть как-то, о таком примере как стартовый я и не мечтаю).
ООП не отжило своё. ООП более-менее удовлетворительно позволяет решать большинство задач. А для некоторых задач ООП подходит лучше других парадигм. Современная тенденция - не надо замыкаться исключительно на ООП, нужно выбирать парадигму, наиболее подходящую для решения данной задачи.

Вам ссылку на статью, серию статей, книгу? Какой объём информации Вас интересует?
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.09.2016, 19:33
Цитата Сообщение от Shamil1 Посмотреть сообщение
Не понял разницы. Компилятор, когда возможно, оптимизирует switch таблицей переходов. В данном случае это возможно. То есть, сопоставление по образцу в приведённом мной коде делается через таблицу переходов (jumps tabel).
При этом лишний переход никуда не девается. Виртуальный метод его ликивдирует. При этом если тип однозначно определен при вызове виртуальный метод вызывается явно а не через индирект вызов.

Добавлено через 1 минуту
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вы предлагаете мне показать преимущество использования неизменяемых переменных на примере кода, который вообще не использует никаких переменных...
Это не преимущества. Это куча тормозов и съеденного стека.

Добавлено через 1 минуту
Цитата Сообщение от Shamil1 Посмотреть сообщение
Зачем в С++ добавили возможность объявлять аргументы функции и методы класса const?
Для того чтобы защитить передаваемые по ссылке данные от случайного изменения. Надеюсь понимаете разницу между принципиальной невозможностью изменения данных и запретом на их изменение в определенном месте?

Добавлено через 3 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Если их нельзя изменять, то упрощается отладка/чтение кода программистом и компилятор имеет больше возможностей для оптимизации.
Бред. Во первых чтение не упрощается а усложняется потому как код становится гораздо запутанней. Усложнение же восприятия алгоритма - источник багов. Это из серии - давайте арабские цифры заменим римскими (тоже букофки)и скажем что это круче чем алгебра.

Добавлено через 2 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Например, в С++ нельзя связывать переменные. (Есть только присваивание - связывание переменной и значения).
Как это нельзя? А ссылки и указатели?
Цитата Сообщение от Shamil1 Посмотреть сообщение
А в некоторый языках, например, записи A=B и B=A эквивалентны.
Можно и в С++ так оператор присваивания перегрузить для нужных типов. Другое дело что это редко когда нужно. Обычно указателей достаточно.

Добавлено через 4 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Вы предлагаете мне показать преимущество использования неизменяемых переменных на примере кода, который вообще не использует никаких переменных...
Как это не использует? x accuracy и guess переменные назначение которых насколько понимаю переполнить стек. Для ОЗУ на перфоленте кстати самое то. бумага все стерпит, главное что основная масса значений будет на перфоленте, будет записываться по порядку, будет считываться в обратном порядке (т.е. с оптимальным способом перемотки)
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
20.09.2016, 20:53
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Это не преимущества. Это куча тормозов и съеденного стека.
Если компилятор нормальный, то стек переполняться не будет.
Тормозов нет. Вы не сможете ускорить этот код даже на 1 микросекунду.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Бред. Во первых чтение не упрощается а усложняется потому как код становится гораздо запутанней
Обычно код становится проще. Обычно код в функциональном стиле является 1 к 1 отражением алгоритма.
Кроме того, код становится короче, что так же упрощает понимание (больше информации умещается на один экран).

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Как это нельзя? А ссылки и указатели?
Нельзя. Присваивание одной переменной значения другой переменной не является связыванием переменных. Создание синонима имени также не является связыванием переменных.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Можно и в С++ так оператор присваивания перегрузить для нужных типов. Другое дело что это редко когда нужно. Обычно указателей достаточно.
Перегрузкой операторов нельзя добиться связывания переменных.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Для того чтобы защитить передаваемые по ссылке данные от случайного изменения. Надеюсь понимаете разницу между принципиальной невозможностью изменения данных и запретом на их изменение в определенном месте?
Внутри функции нет принципиальной возможности менять константные аргументы. Иначе не было бы смысла в такой защите.
У меня есть неизменяемые переменные (readonly) и изменяемые переменные. Зачем мне может понадобиться принципиальная возможность менять readonly переменные? если я, наоборот, хочу, чтобы их нельзя было поменять (даже лишнее слово пишу в коде)?

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
При этом лишний переход никуда не девается. Виртуальный метод его ликивдирует.
Откуда "лишний" переход и куда?
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.09.2016, 21:02
Цитата Сообщение от Shamil1 Посмотреть сообщение
Откуда "лишний" переход и куда?
Вызов функкции - переход номер раз. Свитч (даже по таблице) - переход номер двас. Возврат переход номер трис.
Виртуалный метод - вызов по таблице - переход номер раз. Возврат - переход номер двас.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
20.09.2016, 22:28
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
ызов функкции - переход номер раз. Свитч (даже по таблице) - переход номер двас. Возврат переход номер трис.
Виртуалный метод - вызов по таблице - переход номер раз. Возврат - переход номер двас.
А Вы учли, что в первом случае вызов функции не виртуальный? Более того, он может заинлайнится.

з.ы. А если вызов не заинлайнился, значит функция достаточно большая, чтобы не считать затраты на вызов. Хотя, лично я считаю, что невиртуальный вызов + переход по таблице (не вызов, а переход... стек не задействован) не займут больше времени, чем виртуальный вызов.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
20.09.2016, 23:29
Цитата Сообщение от Shamil1 Посмотреть сообщение
Внутри функции нет принципиальной возможности менять константные аргументы.
Внутри функции данной функции нет принципиальной необходимости менять агрументы объявленные костантными. Но это не означает что такой необходимости нет в других функциях работающих с этими же данными.

Добавлено через 11 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
А Вы учли, что в первом случае вызов функции не виртуальный?
А вот это уже не имеет никакой разницы. поскольку основная задержка не в типе вызова а в получении данных инстанса. До или после вызова эти данные получаются не имеет никакой разницы.

Добавлено через 1 минуту
Цитата Сообщение от Shamil1 Посмотреть сообщение
Если компилятор нормальный, то стек переполняться не будет.
Тормозов нет. Вы не сможете ускорить этот код даже на 1 микросекунду.
Здесь не хвостовая рекурсия. так что залепит стек по полной. А стек он быстрый только пока живет в кеше, поэтому стоит минимизировать а не максимизировать количество вложенных вызовов.

Добавлено через 1 минуту
Цитата Сообщение от Shamil1 Посмотреть сообщение
стек не задействован
Если стек помещается в кеш его задействование вообще ничего не стоит.
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
21.09.2016, 03:04
Цитата Сообщение от Igor3D Посмотреть сообщение
Что в нем наивно (или просто плохо)
Draw - ф топку.

имена переменных которые начинаются с подчеркиваний - ф топку.

17.6.4.3.2 Global names [global.names]
1 Certain sets of names and function signatures are always reserved to the implementation:
— Each name that contains a double underscore _ _ or begins with an underscore followed by an uppercase
letter (2.12) is reserved to the implementation for any use.
— Each name that begins with an underscore is reserved to the implementation for use as a name in the
global namespace.
если кто не в курсе,
в качестве глобальных имен могут быть макросы.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,223
Записей в блоге: 2
21.09.2016, 10:24  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
Современная тенденция - не надо замыкаться исключительно на ООП, нужно выбирать парадигму, наиболее подходящую для решения данной задачи.
Какое удобное (мутное) слово "парадигма" Ладно, давайте использовать его. Вот парадигма(ы) ООП мне хорошо известны, а о парадигмах того же ФП - ничего. Все что я слышу типа "а вот здесь можно вот так - и это круто". Конечно в каких-то ситуациях какой-то язык может оказаться куда эффективнее, так что с того? Не вижу "парадигм", а лишь "подробности языка".

Рекомендация "выбирать удачную парадигму" выглядит вяло. Напр на этом форуме я предложил работающему на хаскеле неск задач и сравнить с плюсовой реализацией. Первой было "найти расстояние от точки до отрезка" (что нередко оказывается затруднительным для знатоков). Ответ был - здесь хаскель не имеет каких-то преимуществ, задачка слишком банальна. Было предложено решить ее на хаскеле итеративно. Остроумно, я бы никогда не догадался, но зачем? Вторая задачка - то же самое. Третью я предложил из фундаментальных, вот там что-то интересное мелькнуло, но .. далековато от жизни. В общем, отчетливо видно что "задача подгоняется под язык", я не увидел никаких концепций, принципов, парадигм, а лишь "интересную игру в необычное" (кстати хочу и сам попробовать )

С чисто практической, утилитарной точки зрения выбор удачной парадигмы - голубая мечта, учитывая что основную массу времени программиста занимает рутинная работа и имеется багаж наработок и библиотек. Вряд ли кто станет искать парадигму когда надо сделать работу в срок. "Если это новое так хорошо, то почему оно не задавило старое?" (да, здравый смысл обывателя). Как в свое время ООП задавило процедурное.

Цитата Сообщение от Shamil1 Посмотреть сообщение
Вам ссылку на статью, серию статей, книгу? Какой объём информации Вас интересует?
Об этом я уже говорил - меня устроил бы простой, человеческий, пример сравнимый со стартовым. Только пожалуйста без заумностей и "возвращения Мухтара". Естественная задача которые программист решает часто

Не по теме:

Да, и, в конце-концов, перестаньте "кормить тролля". Ну увлекается человек "скоростью", сам переболеет, "и это пройдет"

0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
21.09.2016, 12:49
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Внутри функции данной функции нет принципиальной необходимости менять агрументы объявленные костантными. Но это не означает что такой необходимости нет в других функциях работающих с этими же данными.
Данные, может, и те же, а переменные уже другие. Если есть принципиальная необходимость менять эти данные где-нибудь в другом месте, то... используйте в другом месте изменяемую переменную.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Здесь не хвостовая рекурсия.
Хвостовая. Компиляторы Haskell/F# её разворачивают.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
А вот это уже не имеет никакой разницы.
То есть, лишняя косвенная адресация (обращение к ТВМ) - это никакой разницы, а обращение к таблице переходов - это "тормоза"?

Добавлено через 23 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Не вижу "парадигм", а лишь "подробности языка".
Если Вам нужно посчитать сумму элементов массива, Вы можете написать цикл. Или можете написать myArray.Sum(). Второй вариант в функциональном стиле ("использует парадигму ФП").
Если Вам нужно выполнить какое-то действие для каждого узла дерева, Вы можете использовать шаблон Посетитель: подготовить базовый класс, затем пронаследоваться от него и перегрузить нужные методы, добавив в них выполнение требуемого действия. Или можете написать ForEach(myAction).

Цитата Сообщение от Igor3D Посмотреть сообщение
"Если это новое так хорошо, то почему оно не задавило старое?" (да, здравый смысл обывателя). Как в свое время ООП задавило процедурное.
Вы же не пишите класс для решения любой задачи? Когда удобнее, Вы пишите функцию вне классов. То есть, Вы в каждом случае выбираете между двумя парадигмами, потому что обе Вам хорошо известны и обе можно использовать в рамках выбранного Вами языка. Если бы Вам была хорошо известна ФП, Вы бы выбирали между ФП и ООП.

Цитата Сообщение от Igor3D Посмотреть сообщение
С чисто практической, утилитарной точки зрения выбор удачной парадигмы - голубая мечта, учитывая что основную массу времени программиста занимает рутинная работа и имеется багаж наработок и библиотек.
Вы правы. У Вас не получится перейти на Haskell. Ну, разве что Вы решите бросить текущую работу и найти вакансию "начинающий прогрммист Хаскел" со смешной (потому что начинающий) зарплатой. И даже в этом случае, скорее всего, не получится из-за того, что в Вашем городе нет вакансий "прогрммист Хаскел".
(Кроме приличного багажа наработок у Вас ещё и коллеги, которые понимают С++ и не понимают Хаскель).

Цитата Сообщение от Igor3D Посмотреть сообщение
Да, и, в конце-концов, перестаньте "кормить тролля".
Я использую это как стимул покопаться в коде, который выдают компиляторы F#/C#.

Добавлено через 6 минут
Цитата Сообщение от Igor3D Посмотреть сообщение
Естественная задача которые программист решает часто
Хорошо, попробую (позже).
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,223
Записей в блоге: 2
21.09.2016, 13:07  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
У Вас не получится перейти на Haskell
Вы переоцениваете мой энтузиазм В моих планах лишь "ознакомиться"

Цитата Сообщение от Shamil1 Посмотреть сообщение
Если Вам нужно посчитать сумму элементов массива, Вы можете написать цикл. Или можете написать myArray.Sum(). Второй вариант в функциональном стиле ("использует парадигму ФП").
Если Вам нужно выполнить какое-то действие для каждого узла дерева, Вы можете использовать шаблон Посетитель: подготовить базовый класс, затем пронаследоваться от него и перегрузить нужные методы, добавив в них выполнение требуемого действия. Или можете написать ForEach(myAction).
Думаю что понимаю к чему Вы, но все эти std::for_each, find, all_of (и еще масса всякой всячины которую так усердно заучивает молодежь) - ну никак не тянут они на "концепцию/парадигму" - по той простой причине что то же самое можно сделать простецким for. Это экономия пары строк (ценой забивания памяти/головы)

Цитата Сообщение от Shamil1 Посмотреть сообщение
Если бы Вам была хорошо известна ФП, Вы бы выбирали между ФП и ООП.
Хмм.. ну наверное - если бы были "вкусные плюшки" Но вот их почему-то не видно...
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
21.09.2016, 13:07

ООП пример
Доброго времени суток. Тут отыскался один пример в конспекте. Записал на лекции спустя рукава. Хочу восстановить. Где-то что-то...

Пример ООП на D
Пример из книги Язык программирования D Андрей Александреску стр.49 1.6. Интерфейсы и классы Даны числа, нужно найти минимум,...

Не работает пример с ООП
Здраствуйте. Помогите пожалуйста, я не понимаю, как создать простейший объект (например из двух переменных) в паскале и что для этого...

Нужен пример использования ООП
Вот ООП в JavaScript есть, но каким боком его можно использовать? Я еще не сталкивался с такими вещами, в которых процедурно-функциональный...

Нужен пример с использованием ООП
Дарова всем, хотел спросить вас, может кто знает ссылку на инфу о объект - ориентированном программировании в Visual Basic? Я уже весь инет...


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

Или воспользуйтесь поиском по форуму:
80
Ответ Создать тему
Новые блоги и статьи
Локальный http сервер
Argus19 17.10.2026
Локальный http сервер На работе, на двух локальных компьютерах круглосуточно работают программы опроса приборов с записью в книги Excel,которые раз в сутки записываются на сервер компании. Т. к. . . .
Копировать Windows на новый диск на UEFI
damix 17.10.2026
https:/ / uriesk. wordpress. com/ 2016/ 11/ 01/ move-window-10-to-ssd-on-a-uefi-dualboot-system-with-basic-linux-tools/ TL DR Вставляем диск, а старый подключаем через переходник, грузимся с лайва. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Программный домашний кинотеатр
russiannick 27.09.2026
Сподобился на программный домашний кинотеатр. В качестве ЯВУ по традиции выбрал js. В помощники взял Яндекс-Алису. Было создано три зала на разные интересы. исторические и ретро сериал Хичкок. . .
Беседа с ИИ о программистах, недопускающих к созданию и правке кода генеративные ИИ и причины этого
zorxor 21.09.2026
Раньше я радовался или получал некоторые эмоции, пусть небольшие, но всё же, от самого процесса написания кода, рекомпиляции и запуска, видя постепенное развитие программы и прочее. А теперь лень. . .
Мобильное приложение ColorStep
pavlinmavlin 17.09.2026
Реализовал приложение Красный, Зеленый, Синий в Unity3d + c#. Название изменил на ColorStep. Приложение прошло модерацию и теперь доступно для скачивания. Делал его сам, шаг за шагом — и вот,. . .
Запрет дублирования строк в табличной части
Maks 13.09.2026
Реализация из решения ниже выполнена на нетиповом справочнике "Нормы ТО" с табличной часть "Виды ТО", разработанного в КА2, со следующими реквизитами: - ВидТО (СправочникСсылка. ВидыТО); - ВидГСМ. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru