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

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

13.09.2016, 11:26. Показов 9286. Ответов 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
22.09.2016, 17:48
Студворк — интернет-сервис помощи студентам
Цитата Сообщение от Igor3D Посмотреть сообщение
Думаю что понимаю к чему Вы, но все эти std::for_each, find, all_of (и еще масса всякой всячины которую так усердно заучивает молодежь) - ну никак не тянут они на "концепцию/парадигму" - по той простой причине что то же самое можно сделать простецким for. Это экономия пары строк (ценой забивания памяти/головы)
1. Эта функция по заданному значению A меняет координаты всех вершин фигуры так, что для каждой вершины x2 = x1 cosA - y1 sinA и y2 = x1 * sinA - y1 cosA.
2. Это поворот на угол А.

Согласитесь, что вторая формулировка удобнее и понятней. Вы поймёте её быстрее уже хотя бы потому, что это всего 3 слова, а не 30.
Кроме этого, Вы получите дополнительный положительный эффект за счёт того, что больше кода будет умещаться на экране. Меньше придётся скролить, чтобы вспомнить, что было выше.

Но, чтобы получить максимальную пользу от использования этих абстракций, нужно не только использовать их в коде, но и использовать их при составлении алгоритма.
Кликните здесь для просмотра всего текста
Несколько лет тому назад я начал изучать F#, но месяца через два забросил. Я разобрался с синтаксисом и писал небольшие программы, но не видел никаких преимуществ использования F#, потому что, фактически, я придумывал решение задачи на C#, а затем в уме переводил его на F#. В таком использовании F#, действительно, мало смысла.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,211
Записей в блоге: 2
22.09.2016, 18:10  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
1. Эта функция по заданному значению A меняет координаты всех вершин фигуры так, что для каждой вершины x2 = x1 cosA - y1 sinA и y2 = x1 * sinA - y1 cosA.
2. Это поворот на угол А.
Согласитесь, что вторая формулировка удобнее и понятней.
Безусловно (только для y2 там плюс), в уме все оперируют понятием "поворот", подробностями плюсов и минусов занимается разве что товарищ в соседней теме Но по-моему это совершенно одинаково везде, не вижу здесь никакой связи с ФП или ООП

Цитата Сообщение от Shamil1 Посмотреть сообщение
Несколько лет тому назад я начал изучать F#, но месяца через два забросил. Я разобрался с синтаксисом и писал небольшие программы, но не видел никаких преимуществ использования F#, потому что, фактически, я придумывал решение задачи на C#, а затем в уме переводил его на F#. В таком использовании F#, действительно, мало смысла.
Знакомая ситуация, вот я и спрашивал какими принципами я должен руководствоваться. Отрицание знакомого меня не особо смущает, но вот что же взамен - неясно
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
22.09.2016, 18:29
Цитата Сообщение от Igor3D Посмотреть сообщение
только для y2 там плюс
Точно.

Цитата Сообщение от Igor3D Посмотреть сообщение
Но по-моему это совершенно одинаково везде, не вижу здесь никакой связи с ФП или ООП
Я про использование абстракций типа map, filter, fold. Это не просто "способ записать по-другому".

Цитата Сообщение от Igor3D Посмотреть сообщение
Знакомая ситуация, вот я и спрашивал какими принципами я должен руководствоваться.
Я изучал Хаскель, писал программы на нём, и в как-то само собой получилось. Ну и, полагаю, помогло то, что в C# добавили функциональные возможности, и я их использую.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
28.09.2016, 01:01
Цитата Сообщение от Shamil1 Посмотреть сообщение
Согласитесь, что вторая формулировка удобнее и понятней. Вы поймёте её быстрее уже хотя бы потому, что это всего 3 слова, а не 30.
Кроме этого, Вы получите дополнительный положительный эффект за счёт того, что больше кода будет умещаться на экране. Меньше придётся скролить, чтобы вспомнить, что было выше.
Более понятен и универсален третий вариант - умножение матрицы вершин на матрицу преобразования. А соответственно если по уму делать то реализуется перегрузкой оператора умножения. Чтоб оно все просто и логично было матан учить надо а не всякие трясины раскапывать.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,211
Записей в блоге: 2
28.09.2016, 07:40  [ТС]
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Более понятен и универсален третий вариант - умножение матрицы вершин на матрицу преобразования.
С Вашими корявыми самопальными терминами этот вариант наименее понятен. Подучите "матан" что ли
1
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
28.09.2016, 17:30
Я упоминал (на первой странице), но не привёл ещё один вариант. Он является развитием Варианта 2 (устраняет недостаток "пропадание" полиморфизма).

Вариант 3:
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
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
void Main()
{
    var shape = new Circle(new WinFormCircleDrawer());
    shape.Draw();
}
 
// Define other methods and classes here
public abstract class Shape<T>
    where T : Shape<T>
{
    public double CoordX { get; set; } // Атрибут - координата X
    public double CoordY { get; set; } // Атрибут - координата Y
 
    public IShapeDrawer<T> Drawer { get; private set; }
    
    protected Shape(IShapeDrawer<T> drawer)
    {
        Drawer = drawer;
    }
 
    public virtual void Draw()
    {
        Drawer.Draw((T)this);
    }
}
 
public class Circle : Shape<Circle>
{
    public double Radius { get; set; } // Атрибут - длина радиуса   
 
    public Circle(IShapeDrawer<Circle> drawer) : base(drawer) {}
}
 
public class Square : Shape<Square>
{
    public double Side { get; set; } // Атрибут - длина стороны квадрата
 
    public Square(IShapeDrawer<Square> drawer) : base(drawer) { }
}
 
public interface IShapeDrawer<T> 
    where T : Shape<T>
{
    void Draw(T shape);
}
 
public abstract class WinFormShapeDrawer<T> : IShapeDrawer<T>
    where T : Shape<T>
{
    public abstract void Draw(T shape);
}
 
public class WinFormCircleDrawer : WinFormShapeDrawer<Circle>
{
    public override void Draw(Circle shape)
    {
        Console.WriteLine("Have drawn the circle");
    }
}
 
public class WinFormSquareDrawer : WinFormShapeDrawer<Square>
{
    public override void Draw(Square shape)
    {
        Console.WriteLine("Have drawn the square");
    }
}
Отличия от Варианта 2:
Чтобы не выбирать каждый раз для рисования правильный Рисователь, мы сохраняем ссылку на правильный Рисователь в самом классе Shape.

Использовал Generic не обязательно, как и в Варианте 2. Но за счёт Generic мы получаем дополнительную надёжность: нельзя скомпилировать код, который для рисования Кругов будет пытаться использовать Рисователь Квадратов.

Чтобы не указывать тип Рисователя везде в коде, где создаются наши объекты, придётся использовать шаблон Абстрактная Фабрика.

Недостатком Варианта 3 является то, что мы связываем классы Фигура и Рисователь. Проявляется этот недостаток, когда наша программа состоит из нескольких независимых модулей. Даже те модули, которым никогда не нужно рисовать Фигуры, должны знать, что существует интерфейс Рисователь для рисования Фигур.

Для устранения этого недостатка необходимо отделить мух от котлет объекты от действий с ними. Отдельно - классы Shape с данными, отдельно - классы ShapeSomethingService с действиями. В результате от подхода, основанного на наследовании, приходим к подходу, который в принципе не требует наследования (а значит, не требует и классов), хотя и "по привычке" реализуется с помощью наследования.

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

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

2. Также, в традиционных "бизнес-приложениях" АТД предпочтительней Классов, так как обеспечивают большую надёжность. Они позволяют многие бизнес-правила закладывать прямо в типы, то есть, код, нарушающий бизнес правила, даже не скомпилируется.


з.ы. По прежнему не теряю надежды привести пару простых примеров - по одному на каждый из пунктов.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
28.09.2016, 18:29
Цитата Сообщение от Igor3D Посмотреть сообщение
С Вашими корявыми самопальными терминами этот вариант наименее понятен.
Откройте учебник ВГ. Именно так операция преобразования точек модели и формулируется- умножение матрицы вершин на матрицу преобразования базиса.

Добавлено через 7 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Функциональные языки обычно подходят лучше "Си-подобных" императивных языков для задач, где функции (в основном) вызываются ради получения результата, а не ради побочных эффектов. Это вычислительные ("математические") задачи, обработка данных, автоматы и т.п.
Бред. К примеру есть набор коллайдеров каждый из коллайдеров должен обеспечивать определение попадания точки внутрь, рассчет пересечения с лучем и расчет пересечения с другим коллайдером. При этом каждый из инстансов коллайдера может трансформироваться (т.е менять свое положение в пространстве). Тут как не крути а с объектами будет удобнее, особенно учитывая что каждый тип коллайдера (для разных шейпов примитивов) хранит разные данные.

Добавлено через 4 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
Классов, так как обеспечивают большую надёжность.
Тоже бред. ООП в этом плане гораздо большую надежность и логичность предоставляет. Хотя бы потому как возможные операции сгруппированы по типам а не по операциям. Соответственно код легче для понимания и расширения.

Добавлено через 3 минуты
Цитата Сообщение от Shamil1 Посмотреть сообщение
з.ы. По прежнему не теряю надежды привести пару простых примеров - по одному на каждый из пунктов.
Их не существует. В силу ограниченности ФП по сравнению с ООП. Замыкание сильно урезанный частный случай объекта.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
28.09.2016, 19:54
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Бред. К примеру есть набор коллайдеров каждый из коллайдеров должен обеспечивать
В данном вопросе мнение Тима Суини выглядит гораздо более авторитетным, чем Ваше.
(Тим Суини - программист-разработчик компьютерных игр, основатель компании Epic Games, создатель игрового движка Unreal Engine).

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

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Хотя бы потому как возможные операции сгруппированы по типам а не по операциям. Соответственно код легче для понимания и расширения.
Ничем не обоснованное утверждение.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
28.09.2016, 20:50
Цитата Сообщение от Shamil1 Посмотреть сообщение
В данном вопросе мнение Тима Суини выглядит гораздо более авторитетным, чем Ваше.
В этом плане Тим Суини ноль без палочки. Хотя бы потому что Unreal Engine своего движка коллизий не имеет а пользует готовый PhysX, и тот работает только с поверхностями первого порядка. В этом плане авторитетным могу принять только мнение разработчиков к примеру движка коллизий SolidWorks или подобного софта. Но он абсолютно весь на ООП парадигме, причем даже в качествве скриптового языка отказались от ЛИСП в пользу ООП-языков еще в начале 90-х .

Добавлено через 6 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Большая надёжность обеспечивается тем, что некоторые типы ошибок отлавливаются на этапе компиляции. То есть, их в принципе не может быть.
Главный вопрос в наборе типов ошибок которые отлавливаются. К примеру при создании Ада рулила концепция что запрет на смесь разных типов в одном выражении позволят отлавливать абсолютно все ошибки. В результате ракеты взрывались из за ошибок в приведении типов для обхода такого запрета там где это было необходимо. От недопонимания задачи ни парадигма ни компилятор в принципе вылечить не в состоянии.
На самом же деле как оказалось гораздо большую типобезопасность дает не запрет на смесь типов выражениях а определение алгебры над сущностями. к примеру вектор координата складывается только с ветором смещение а произведение вектора скорость на время дает смещение. Т.е. стандартная ООП-я перегрузка операторов.

Добавлено через 6 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Ничем не обоснованное утверждение.
БольшИм удобством при добавлении нового типа как минимум.
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
29.09.2016, 08:03
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
В этом плане Тим Суини ноль без палочки. Хотя бы потому что Unreal Engine своего движка коллизий не имеет а пользует готовый PhysX, и тот работает только с поверхностями первого порядка. В этом плане авторитетным могу принять только мнение разработчиков к примеру движка коллизий SolidWorks или подобного софта. Но он абсолютно весь на ООП парадигме, причем даже в качествве скриптового языка отказались от ЛИСП в пользу ООП-языков еще в начале 90-х .
Если Вы считаете, что мнение человека, не написавшего SolidWorks, не имеет значения, то зачем Вы приводите своё мнение?
Какое отношение имеет PhysX к задаче, упомянутой Вами в предпоследнем сообщении? Есть там метод, в который можно передать 10 тыс объектов, которые могут измениться другим потоком? Или эта библиотека состоит из чистых (как в ФП) функций?
Достоинство PhysX заключается в наличии низкоуровневого кода под множество разных архитектур, включая xbox и gpu. Причём тут ООП?
Зачем Вы упоминаете разработчиков SolidWorks, если Вы не привели их мнение. То, что они пишут на C++, не означает, что они считают, что этот язык идеально подходит для данной задачи. Unreal Engine, кстати, написан на C++ и немного cg/hlsl.

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

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
На самом же деле как оказалось гораздо большую типобезопасность дает не запрет на смесь типов выражениях а определение алгебры над сущностями. к примеру вектор координата складывается только с ветором смещение а произведение вектора скорость на время дает смещение. Т.е. стандартная ООП-я перегрузка операторов.
Каким образом здесь поможет перегрузка? Функция на C++ не отличит вектор скорости от другого вектора. А вот, например, в F# можно каждой переменной задать единицы измерения. И компилятор не позволит, например, складывать путь и скорость.

Вы, видимо, не поняли того, что я написал. Безопасность, о которой я писал, не имеет отношения к приведению типов. Я писал о том, что код, нарушающий "бизнес-правила", не компилируется.
Например, есть правило "корзину нельзя оплатить, если в ней нет товаров". В C++ Вы добавите проверку и будете сообщать об ошибке во время исполнения. В F# Вы получите ошибку во время компиляции. То есть, код, оплачивающий пустую корзину, нельзя скомпилировать.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
БольшИм удобством при добавлении нового типа как минимум.
БольшИм неудобством при добавлении нового типа?
Надёжность - это когда Вы добавили новую сущность или новое действие над ней, и компилятор выдал ошибки во всех местах, в которых надо внести изменения в связи с этим добавлением.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,211
Записей в блоге: 2
29.09.2016, 09:36  [ТС]
Цитата Сообщение от Shamil1 Посмотреть сообщение
Чтобы не выбирать каждый раз для рисования правильный Рисователь, мы сохраняем ссылку на правильный Рисователь в самом классе Shape.
Точнее "назначается", шейп его хранит и вызывает, но подробностей не знает, видит лишь интерфейс. Все ясно, но.. я не узнал ничего нового

Цитата Сообщение от Shamil1 Посмотреть сообщение
Каким образом здесь поможет перегрузка? Функция на C++ не отличит вектор скорости от другого вектора. А вот, например, в F# можно каждой переменной задать единицы измерения. И компилятор не позволит, например, складывать путь и скорость.
Заставить отличать несложно
C++
1
2
3
4
5
6
7
8
9
struct Coordinate {
 float x, y, z;
// operators
};
 
struct Vector {
 float x, y, z;
// operators
};
Хотя на практике так делают редко
0
Модератор
Эксперт функциональных языков программирования
3141 / 2289 / 469
Регистрация: 26.03.2015
Сообщений: 8,920
29.09.2016, 10:48
Цитата Сообщение от Igor3D Посмотреть сообщение
Хотя на практике так делают редко
Да. Потому что это достаточно трудоёмко. Нужно создать новый класс (желательно, в отдельном файле), операторы для него и так далее. В F# же достаточно добавить одну-две строки, поэтому в F# так делаю гораздо чаще. Например
F#
1
2
3
type EmailAddress = EmailAddress of String
type ZipCode = ZipCode of String
type StateCode = StateCode of String
Но я имел ввиду другое. В F# можно переменным добавить единицы измерения. Тогда нельзя будет складывать километры и часы, но можно будет делить, чтобы получить км/ч.
F#
1
2
3
4
5
6
7
8
9
[<Measure>] type m
[<Measure>] type sec
[<Measure>] type kg
 
let distance = 1.0<m>    
let time = 2.0<sec>    
let speed = 2.0<m/sec>    
let acceleration = 2.0<m/sec^2>    
let force = 5.0<kg m/sec^2>
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.09.2016, 00:23
Цитата Сообщение от Shamil1 Посмотреть сообщение
Да. Потому что это достаточно трудоёмко. Нужно создать новый класс (желательно, в отдельном файле), операторы для него и так далее. В F# же достаточно добавить одну-две строки, поэтому в F# так делаю гораздо чаще.
Если при этом учесть что на один тип делиться/умножаться может совсем не так как на другой то получится что способ пользуемый в C++ гораздо универсальней. Пример - умножение униформ-матрицы на точку и вектор. Суть - в четвертой униформ-координате у точки 1 у вектора 0. Но хранить вектора точки в униформе очень неудобно. Соответственно гораздо логичней завести два разных типа которые умножаются на матрицу по разному (с подстановкой в 0 или 1 в формулы в опреаторе). При этом точка складывается только с вектором а с точкой складываться не может. Вычитание точек дает вектор. Сложение точки и вектора дает точку. Сложение векторов дает вектор.

Добавлено через 5 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
Потому что это достаточно трудоёмко.
В случае с вектором и точкой это 15 минут работы на все 4 (2D и 3D). Если учесть что пользуется потом повсеместно то относительная трудоемкость в районе 0. Т.е. фактически делал 1 вечер нужные типы, пользую ежедневно уже как минимум пол года без изменений.

Добавлено через 39 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
В F# Вы получите ошибку во время компиляции.
Ну и каким образом компилятор может определить пуста она или нет в компайл тайме? Такое только библиотеками в рантайме делается.
Цитата Сообщение от Shamil1 Посмотреть сообщение
В C++ Вы добавите проверку и будете сообщать об ошибке во время исполнения.
Давно используется абсолютно другой подход - при изменении списка товаров в корзине для пустой корзины отключается команда (событие) "оплатить". Большинство библиотек событийного управления при этом обеспечивают и отключение/скрытие элементов управления для отключенных комманд

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

Добавлено через 7 минут
Цитата Сообщение от Shamil1 Посмотреть сообщение
В F# можно переменным добавить единицы измерения. Тогда нельзя будет складывать километры и часы, но можно будет делить, чтобы получить км/ч.
Теперь еще пример. Время и шаг по времени (дифференциал). И то и то измеряется в секундах. При этом Время со Временем можно только сравнивать, а складывать только с дифференциалом. При этом вычитание времени из времени дает дифференциал. При этом время нельзя добавить/вычесть из дифференциала а можно только добавить к времени дифференциал. Причем встречаются такие задачи в имитационном моделировании процессов на каждом шагу. С++ с такими задачами справляется с легкостью, причем основная часть шаблонизируется. Да кстаи предыдущий пример - вектор и точка тоже из этой серии. фактически вектор это дифференциал точки.
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
30.09.2016, 03:53
Цитата Сообщение от Igor3D Посмотреть сообщение
Что в нем наивно (или просто плохо), а что остается верным и правильным?
К С++ коду я придираться не буду (хотя можно было бы), но вот эти coordX, coordY в Shape - это плохо.

Цитата Сообщение от Shamil1 Посмотреть сообщение
Предлагайте свои варианты решения упомянутых проблем.
Цитата Сообщение от Shamil1 Посмотреть сообщение
Суть в том, что то, что мы привыкли делать с использованием ООП можно делать и с использование Алгебраических Типов Данных. Плюсы АТД есть, но они не принципиальны в данном случае.
В плюсах АТД делается через variant + static_visitor. Но нужно четко понимать, когда АТД лучше, а когда - нет.

Цитата Сообщение от Shamil1 Посмотреть сообщение
К сожалению, Хаскель не является лучшим функциональным языком.
А кто является?

Цитата Сообщение от Shamil1 Посмотреть сообщение
Сейчас, пожалуй, лучший (наиболее перспективный) - это F#
Это не чисто функциональный язык. И не везде net котируется.

Fulcrum_013
Вот тебе рантайм полиморфизм за пару минут на коленке:
Haskell
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
{-# LANGUAGE ExistentialQuantification #-}
 
module Main where
 
class Shape_ a where
  draw :: a -> IO ()
 
data Shape = forall a. Shape_ a => Shape a
 
data Circle = Circle Double Double Double
data Square = Square Double Double Double
 
instance Shape_ Circle where
  draw _ = print "Circle::draw"
 
instance Shape_ Square where
  draw _ = print "Square::draw"
 
instance Shape_ Shape where
  draw (Shape shape) = draw shape
 
main :: IO ()
main = do
  ch <- getChar
  let x = case ch of 'c' -> Shape (Circle 0 0 5)
                     's' -> Shape (Square 0 0 2)
                     _ -> error "LOL"
  draw x
Вот тебе изменяемые переменные https://wiki.haskell.org/Mutable_variable - прикинь!

Ну а вообще ты славно позоришься со своим "знанием" ФП по многим пунктам, отдаю должное.
0
1980 / 836 / 115
Регистрация: 01.10.2012
Сообщений: 5,211
Записей в блоге: 2
30.09.2016, 05:22  [ТС]
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
Т.е. фактически делал 1 вечер нужные типы, пользую ежедневно уже как минимум пол года без изменений.
Полгода не срок
Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
При этом точка складывается только с вектором а с точкой складываться не может.
И что делать если надо посчитать центр тяжести или даже просто среднее 2 точек? Перелить в векторы и обратно? Тогда чего было играться в концептуальность, просто для удобства написать
C++
1
typedef Vectoу Point;
И вся любовь

Вообще, не лучше ли настроиться более позитивно? Сказать "это все фигня, ООП рулит" (к чему сводятся Ваши посты) ума много не надо.

Цитата Сообщение от ct0r Посмотреть сообщение
Вот тебе рантайм полиморфизм за пару минут на коленке:
Никогда не понимал этого "на коленке" - типа "круто" что ли? Так а в чем крутизна-то? Чем выгоднее банального кода на плюсах?
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.09.2016, 05:37
Цитата Сообщение от Igor3D Посмотреть сообщение
Тогда чего было играться в концептуальность, просто для удобства написать
Цитата Сообщение от ct0r Посмотреть сообщение
В плюсах АТД делается через variant + static_visitor. Но нужно четко понимать, когда АТД лучше, а когда - нет.
У варианта типизация динамическая.

Добавлено через 2 минуты
Цитата Сообщение от Igor3D Посмотреть сообщение
Тогда чего было играться в концептуальность, просто для удобства написать
Для удобств в физической модели. В геометрической точка фактически описывается своим радиус-вектором.
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
30.09.2016, 05:58
Цитата Сообщение от Igor3D Посмотреть сообщение
Никогда не понимал этого "на коленке" - типа "круто" что ли?
"На коленке" - это значит, что код только в иллюстративных целях, и его можно улучшить в некоторых аспектах, не относящихся напрямую к теме.

Цитата Сообщение от Fulcrum_013 Посмотреть сообщение
У варианта типизация динамическая.
Это ATD. Туда можно класть значения только определенных мной типов. Вот boost::any - динамическая.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.09.2016, 06:52
Цитата Сообщение от Igor3D Посмотреть сообщение
Сказать "это все фигня, ООП рулит" (к чему сводятся Ваши посты)
Оно так и есть на самом деле. ФП - тьюринговская трясина и это много раз было доказано

Добавлено через 2 минуты
Цитата Сообщение от ct0r Посмотреть сообщение
Это ATD. Туда можно класть значения только определенных мной типов
в variant тоже только типов определенного набора. НО из этого набора тип определяется динамически.

Добавлено через 2 минуты
Цитата Сообщение от ct0r Посмотреть сообщение
Вот тебе изменяемые переменные https://wiki.haskell.org/Mutable_variable - прикинь!
Я знаю что они там есть. Разговор был о том что их наличие в хаскеле - последний гвоздь в гроб мифу о превосходстве неизменяемых переменных над изменяемыми и соответственно всем бредням о том что изменяемые состояния хуже ФП-безобразий.

Добавлено через 1 минуту
Цитата Сообщение от ct0r Посмотреть сообщение
Ну а вообще ты славно позоришься со своим "знанием" ФП по многим пунктам, отдаю должное.
Ну и кому оно вообще надо это ФП? Все равно его развитие ведет именно к ООП и ничему другому.
0
Игогошка!
 Аватар для ct0r
1801 / 708 / 44
Регистрация: 19.08.2012
Сообщений: 1,367
30.09.2016, 14:16
Fulcrum_013, ну да, прям конкретный-конкретный тип определяется в рантайме. А что это меняет? Я не понял, что ты сказать-то хотел?)

Fulcrum_013, ага, а наличие функций (особенно лямбда) в ооп-языках и const - о том, что ооп отстой. Чувствуешь, что ты чушь опять сказал?

Fulcrum_013, да, прям заметно, что все свои фичи ФП приводит к ООП))) Настолько заметно, что всякие плюсы, джава,..., тащат в себя функциональные элементы.
0
 Аватар для Fulcrum_013
2083 / 1576 / 169
Регистрация: 14.12.2014
Сообщений: 13,614
30.09.2016, 15:23
Цитата Сообщение от ct0r Посмотреть сообщение
const
Надеюсь разница на запрет изменять данные вообще и на запрет изменять их в определенном месте понятна? Кстати константа и переменная это две очень большие разницы.
Цитата Сообщение от ct0r Посмотреть сообщение
ага, а наличие функций (особенно лямбда) в ооп-языках
Начнем с того что функций любого количества переменных а не одной переменной. При этом лямбда ничем от именованной функции не отличается. Единственная причина по котораой она пользуется - нативные делегаты до сих пор не стандартизированы в место них привернут кривой STL-костыль.
Цитата Сообщение от ct0r Посмотреть сообщение
Настолько заметно, что всякие плюсы, джава,..., тащат в себя функциональные элементы.
Когда собаке делать не... она яйца лижит. Это к тащению ФП фич в ООП языки. Кстати наличие внутренней части VMT (делегаты) нисколько концепции ООП не противоречит.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
30.09.2016, 15:23

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
100
Ответ Создать тему
Новые блоги и статьи
Запустил конкурс "тем и промптов для текстовых квестов созданных почти чисто ИИ"
Adler 06.10.2026
Всем привет! За последние три-четыре дня я создал более 16 текстовых квестовых игр используя преимущественно по одному запросу к ИИ на игру. Мне так понравилось смотреть все ветки/ сцены во всех. . .
ИИ не может найти нужный язык в списке
Supersumestria 05.10.2026
Я ему даю вот такое изображение и прошу найти и подчеркнуть немецкий язык. Возвращает он вот это: https:/ / i. **********/ vqBWLe2. png Нужную строчку в 3й колонке просто выдумал. . Это. . .
Новая последняя моя музыка в SUNO
zorxor 05.10.2026
Здравствуйте, дорогие мои друзья! С большой радостью я хотел бы представить вам свою новую последнею музыку, которую сгенерировала мне по моей просьбе нейросеть SUNO. С уважением, zorxor. Это. . .
Nekobox - outbounds[0].transport: unknown transport type: raw
damix 01.10.2026
Фикс ошибки Правым кликом по серверу -> отладочная информация -> edit Заменить "net": "raw", на "net": "tcp", Нажать кнопку reload.
Программный домашний кинотеатр
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