Отказ от ООП - пример C# vs С++ vs Rust
От: Shmj Ниоткуда  
Дата: 17.09.23 09:16
Оценка:
Давайте пока с простейшего примера, потом, возможно, добавлю чуть интереснее:

  C#
namespace ConsoleApp4 {
    internal class Program {
        class Widget {
            public string? ControlName { get; set; }
            public string? ControlId { get; set; }

            public virtual void Render() {
                Console.WriteLine(ControlName + "=" + ControlId);
            }
        }

        class TextEditWidget : Widget {
            public string? Text { get; set; }

            public override void Render() {
                base.Render();
                Console.WriteLine("Text=" + Text);
            }
        }

        class CheckWidget : Widget {
            public bool IsChecked { get; set; }

            public override void Render() {
                base.Render();
                Console.WriteLine("IsChecked=" + IsChecked);
            }
        }

        static void Main(string[] args) {
            List<Widget> widgets = new List<Widget>();

            widgets.Add(new TextEditWidget() { ControlId = "1", ControlName="Text1", Text="text"});
            widgets.Add(new CheckWidget { ControlId = "2", ControlName = "Check1", IsChecked = true});
            
            foreach (var widget in widgets)
            {
                widget.Render();
            }
        }
    }
}


42 строки

  C++
#include <iostream>
#include <string>
#include <vector>
#include <memory>

class Widget {
public:
    std::string controlName;
    std::string controlId;

    Widget(const std::string& controlName, const std::string& controlId) noexcept 
        : controlName(controlName), controlId(controlId) { }

    virtual void Render() {
        std::cout << controlName << "=" << controlId << std::endl;
    }
};

class TextEditWidget : public Widget {
public:
    std::string text;

    TextEditWidget(const std::string& controlName, const std::string& controlId, const std::string& text) noexcept
        : Widget(controlName, controlId), text(text) { }

    void Render() override {
        Widget::Render();
        std::cout << "Text=" << text << std::endl;
    }
};

class CheckWidget : public Widget {
public:
    bool isChecked;

    CheckWidget(const std::string& controlName, const std::string& controlId, const bool isChecked) noexcept
        : Widget(controlName, controlId), isChecked(isChecked) { }

    void Render() override {
        Widget::Render();
        std::cout << "IsChecked=" << isChecked << std::endl;
    }
};

int main() {
    std::vector<std::unique_ptr<Widget>> widgets;

    auto textWidget = std::make_unique<TextEditWidget>("1", "Text1", "text");
    widgets.push_back(std::move(textWidget));

    auto checkWidget = std::make_unique<CheckWidget>("2", "Check1", true);
    widgets.push_back(std::move(checkWidget));

    for (const auto& widget : widgets) {
        widget->Render();
    }

    return 0;
}


59 строк

  Rust
trait Widget {
    fn render(&self);
}

struct BaseWidget {
    control_name: Option<String>,
    control_id: Option<String>,
}

impl Widget for BaseWidget {
    fn render(&self) {
        if let Some(ref name) = self.control_name {
            print!("{}", name);
        }

        print!("=");

        if let Some(ref id) = self.control_id {
            print!("{}", id);
        }

        println!();
    }
}

struct TextEditWidget {
    base: BaseWidget,
    text: Option<String>,
}

impl Widget for TextEditWidget {
    fn render(&self) {
        self.base.render();
        if let Some(ref text) = self.text {
            println!("Text={}", text);
        }
    }
}

struct CheckWidget {
    base: BaseWidget,
    is_checked: bool,
}

impl Widget for CheckWidget {
    fn render(&self) {
        self.base.render();
        println!("IsChecked={}", self.is_checked);
    }
}

fn main() {
    let widgets: Vec<Box<dyn Widget>> = vec![
        Box::new(TextEditWidget {
            base: BaseWidget {
                control_id: Some("1".to_string()),
                control_name: Some("Text1".to_string()),
            },
            text: Some("text".to_string()),
        }),
        Box::new(CheckWidget {
            base: BaseWidget {
                control_id: Some("2".to_string()),
                control_name: Some("Check1".to_string()),
            },
            is_checked: true,
        }),
    ];

    for widget in widgets {
        widget.render();
    }
}


73 строки

Видно что ООП языки — примерно одинаковой компактности, в то время как язык без ООП даже на простейшем примере потребовал писать почти в 2 раза больше строк кода. Хотя там еще добавляется многословность в связи с Option — но кто им виноват, что не использовали ? как в C# на уровне языка, а то постоянно лепят свой Option.

Выводы какие? Даже на простейшем примере видно удобство ООП. А теперь представьте что пример будет реальным — сразу 50 тыс. строк превращаются в 100 тыс.
Re: Отказ от ООП - пример C# vs С++ vs Rust
От: kov_serg Россия  
Дата: 17.09.23 09:54
Оценка: +1 -1 :)
Здравствуйте, Shmj, Вы писали:

S>Давайте пока с простейшего примера, потом, возможно, добавлю чуть интереснее:

S>C# 42 строки
S>C++ 59 строк
S>Rust 73 строки

S>Выводы какие? Даже на простейшем примере видно удобство ООП. А теперь представьте что пример будет реальным — сразу 50 тыс. строк превращаются в 100 тыс.

Никакие. Язык без ООП lua:
require "object"

Widget={ render=function(self) print(self.name.."="..self.id)  end }
TextEditWidget=object(Widget) { render=function(self) inherited(self,"render")() print("Text="..self.text)  end }
CheckWidget=object(Widget) { render=function(self)  inherited(self,"render")() print(("IsChecked=%s"):format(self.is_checked))  end }

local widgets={}
table.insert(widgets, object(TextEditWidget) { id=1, name="Text1", text="text" })
table.insert(widgets, object(CheckWidget) { id=2, name="Check1", is_checked=true })
for i,widget in pairs(widgets) do widget:render() end

10 строк и 12 строк эмуляция ооп
  object.lua
function object(parent)
    return function(prm)
        local res=setmetatable(prm or {},{__index=parent})
        if res.init then res:init() end
        return res
    end
end
function inherited(obj,fn)
    local class=(getmetatable(obj) or {__index={}}).__index
    local parent=(getmetatable(class) or {__index={}}).__index
    return function(...) if parent~=nil then local f=parent[fn] if f~=nil then return f(obj,...) end end end
end
Отредактировано 17.09.2023 9:55 kov_serg . Предыдущая версия .
Re: Отказ от ООП - пример C# vs С++ vs Rust
От: Нomunculus Россия  
Дата: 17.09.23 10:00
Оценка: 3 (1) +3
Здравствуйте, Shmj, Вы писали:

Как ты связал простоту и краткость? Вообще не связанные вещи. Докторская Ландау занимала пять страниц. Теорема Ферма вообще на полях книги была написана.

И с чего ты вдруг решил, что «раз на простом примере… значит». Нифига не значит. Hello World на MFC займет сотни строк. И что? Да ничего
Re: Отказ от ООП - пример C# vs С++ vs Rust
От: T4r4sB Россия  
Дата: 17.09.23 14:23
Оценка: +1
Здравствуйте, Shmj, Вы писали:

S>Видно что ООП языки — примерно одинаковой компактности, в то время как язык без ООП даже на простейшем примере потребовал писать почти в 2 раза больше строк кода. Хотя там еще добавляется многословность в связи с Option — но кто им виноват, что не использовали ? как в C# на уровне языка, а то постоянно лепят свой Option.



Дык примеры неравноценны. Давай в крестах с опционами покажи. Ну и в русте куча лишних строк изза того что не использовано .unwrap_or()
Re[2]: Отказ от ООП - пример C# vs С++ vs Rust
От: Shmj Ниоткуда  
Дата: 17.09.23 15:05
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Дык примеры неравноценны. Давай в крестах с опционами покажи. Ну и в русте куча лишних строк изза того что не использовано .unwrap_or()


Но вообще лучше убрать Option — иначе будем обсуждать иной вопрос, а не сабжевый. Можно сказать что Option протек случайно — не хотел писать конструктор в C#-версии и просто на автомате применил nullable-типы, а в Rust это потребовало писать Option.

Но вот взять базовый класс и вирт. функции с реализацией по умолчанию — в Rust для каждой из них нужно будет писать минимум 1 строчку кода для каждой функции в наследнике. Если, конечно, нет придумать спец. атрибут.
Re: Отказ от ООП - пример C# vs С++ vs Rust
От: SkyDance Земля  
Дата: 17.09.23 15:12
Оценка:
S> widgets.Add(new TextEditWidget() { ControlId = "1", ControlName="Text1", Text="text"});
S>42 строки

Строка длиной в 100 символов.

S> TextEditWidget(const std::string& controlName, const std::string& controlId, const std::string& text) noexcept

S>59 строк

Строка длиной в 115 символов.

S> Box::new(TextEditWidget {

S> base: BaseWidget {
S> control_id: Some("1".to_string()),
S> control_name: Some("Text1".to_string()),
S> },
S> text: Some("text".to_string()),
S> }),
S>73 строки

А тут даже с огроменными отступами самая длинная строка — 57 символов (без отступов и вовсе 41).

Сдается мне, тут имеет место быть сравнение идиотичности форматтеров (или выбраного стиля форматирования).
Re: Отказ от ООП - пример C# vs С++ vs Rust
От: Muxa  
Дата: 17.09.23 17:18
Оценка:
S>Выводы какие? Даже на простейшем примере видно удобство ООП. А теперь представьте что пример будет реальным — сразу 50 тыс. строк превращаются в 100 тыс.

А какую проблему пытаешься решить? Сэкономить место в репе или время набора текста?
Пока что ничего кроме как «и чо?» не приходит в голову в качестве ответного комента.
Отредактировано 17.09.2023 18:19 Muxa . Предыдущая версия .
Re: Отказ от ООП - пример C# vs С++ vs Rust
От: so5team https://stiffstream.com
Дата: 17.09.23 17:55
Оценка: 3 (1)
Здравствуйте, Shmj, Вы писали:

S>[ccode]

S>class Widget {
S>public:
S> std::string controlName;
S> std::string controlId;

S> Widget(const std::string& controlName, const std::string& controlId) noexcept

S> : controlName(controlName), controlId(controlId) { }
S>[/code]

Это вам ChatGPT подсказал такую срань: пометить подобного вида конструктор как noexcept?
Re[2]: Отказ от ООП - пример C# vs С++ vs Rust
От: Shmj Ниоткуда  
Дата: 17.09.23 19:22
Оценка:
Здравствуйте, so5team, Вы писали:

S>Это вам ChatGPT подсказал такую срань: пометить подобного вида конструктор как noexcept?


Это я чего-то попутал на скорую руку. А потом уже лень было исправлять, думал никто не заметит.

Для vector нужно ставить на конструктор перемещения, иначе при расширении будет использовать копирование вместо перемещения.
Re: Отказ от ООП - пример C# vs С++ vs Rust
От: Разраб  
Дата: 17.09.23 23:57
Оценка:
Здравствуйте, Shmj, Вы писали:



S>Выводы какие? Даже на простейшем примере видно удобство ООП. А теперь представьте что пример будет реальным — сразу 50 тыс. строк превращаются в 100 тыс.


https://doc.rust-lang.org/stable/book/ch17-00-oop.html

C# нет смысла сравнивать. Код на rust более читабельный(понятный) чем на плюсах.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[3]: Отказ от ООП - пример C# vs С++ vs Rust
От: so5team https://stiffstream.com
Дата: 18.09.23 05:26
Оценка:
Здравствуйте, Shmj, Вы писали:

S>>Это вам ChatGPT подсказал такую срань: пометить подобного вида конструктор как noexcept?


S>Это я чего-то попутал на скорую руку. А потом уже лень было исправлять, думал никто не заметит.


S>Для vector нужно ставить на конструктор перемещения, иначе при расширении будет использовать копирование вместо перемещения.


Re[4]: Отказ от ООП - пример C# vs С++ vs Rust
От: Shmj Ниоткуда  
Дата: 18.09.23 06:10
Оценка:
Здравствуйте, so5team, Вы писали:

S>>Для vector нужно ставить на конструктор перемещения, иначе при расширении будет использовать копирование вместо перемещения.

S>

Готов выслушать конкретику. Вот пример, который это демонстрирует: https://metanit.com/cpp/tutorial/14.4.php
Re[5]: Отказ от ООП - пример C# vs С++ vs Rust
От: so5team https://stiffstream.com
Дата: 18.09.23 07:36
Оценка:
Здравствуйте, Shmj, Вы писали:

S>>>Для vector нужно ставить на конструктор перемещения, иначе при расширении будет использовать копирование вместо перемещения.

S>>

S>Готов выслушать конкретику.


А я не готов учить вас забесплатно. Вы ChatGPT деньги платите, вот пусть ChatGPT вас и учит.

S>Вот пример, который это демонстрирует: https://metanit.com/cpp/tutorial/14.4.php


Вот уж в прямом смысле "смотришь в книгу, а видишь..."
Re: Отказ от ООП - пример C# vs С++ vs Rust
От: vdimas Россия  
Дата: 18.09.23 09:42
Оценка:
Здравствуйте, Shmj, Вы писали:

S>C#

S>42 строки

S>C++

S>59 строк

Можно было портировать один-в-один строки
widgets.Add(new TextEditWidget() { ControlId = "1", ControlName="Text1", Text="text"});
widgets.Add(new CheckWidget { ControlId = "2", ControlName = "Check1", IsChecked = true});
Re[6]: Отказ от ООП - пример C# vs С++ vs Rust
От: Shmj Ниоткуда  
Дата: 18.09.23 09:46
Оценка:
Здравствуйте, so5team, Вы писали:

S> Вот уж в прямом смысле "смотришь в книгу, а видишь..."


Да вот же:

Почему здесь используется конструктор копирования, а не конструктор перемещения, который в данном случае был бы более предпочтителен? Дело в том, что вектор не уверен, что конструктор перемещения не сгенерирует исключение и в этом случае прибегает к конструктору копирования.

Но в данном случае у нас нет в конструкторе перемещения каких-то моментов, которые могли бы привести к генерации исключения. Поэтому определим конструктор с ключевым словом noexcept:


Тут не учить за бесплатно — а просто признай что не знал этого — не сталкивался. И хотел как бы покичиться — а вышло наоборот, что опозорился.

Или если я не прав — то ткни носом, а не прячься за, мол, учить бесплатно.
Re[4]: Отказ от ООП - пример C# vs С++ vs Rust
От: T4r4sB Россия  
Дата: 18.09.23 09:47
Оценка:
Здравствуйте, so5team, Вы писали:

S>


Для тебя это открытие?
Re[5]: Отказ от ООП - пример C# vs С++ vs Rust
От: so5team https://stiffstream.com
Дата: 18.09.23 09:57
Оценка:
Здравствуйте, T4r4sB, Вы писали:

S>>


TB>Для тебя это открытие?


Нет. Но глубина поражает. Как тут не вспомнить Энштейна с его бесконечностями...
Re[7]: Отказ от ООП - пример C# vs С++ vs Rust
От: so5team https://stiffstream.com
Дата: 18.09.23 10:03
Оценка: 1 (1)
Здравствуйте, Shmj, Вы писали:

S>Или если я не прав — то ткни носом


В цитате-то OK, но очень удивительно, как читая правильные вещи, вы не понимаете что это и где это в вашем коде.

В общем, я давно придерживаюсь мнения, что далеко не всех людей можно научить программировать. А из тех, кого можно научить программировать, далеко не всех можно научить программировать на C++ (а программировать нормально на чистом Си можно научить вообще исчезающе малое количество). Обычно за такой шовинизм мне прилетает. Но вы являетесь отличным доказательством того, что я прав

S>а не прячься за, мол, учить бесплатно.


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

Но, может быть здесь найдется добрая душа, которая объяснит вам в чем дело. Забесплатно.
Re[8]: Отказ от ООП - пример C# vs С++ vs Rust
От: student__  
Дата: 18.09.23 10:46
Оценка:
Здравствуйте, so5team, Вы писали:

S>Но, может быть здесь найдется добрая душа, которая объяснит вам в чем дело. Забесплатно.


А зачем вообще существуют форумы, типа того же RSDN?
Здесь же тоже бесплатно отвечают на вопросы.
Во всяком случае, я ценников на ответах не видел.
Re[9]: Отказ от ООП - пример C# vs С++ vs Rust
От: so5team https://stiffstream.com
Дата: 18.09.23 10:59
Оценка:
Здравствуйте, student__, Вы писали:

S>>Но, может быть здесь найдется добрая душа, которая объяснит вам в чем дело. Забесплатно.


__>А зачем вообще существуют форумы, типа того же RSDN?

__>Здесь же тоже бесплатно отвечают на вопросы.
__>Во всяком случае, я ценников на ответах не видел.

Ага. А потом приходит Шмыж и все портит. Он уже знаменит (по крайней мере в форумах по C/C++) своим нежеланием воспринимать то, что ему пытаются объяснить (а делать это пытались неоднократно). Так что дело именно в нежелании помогать конкретному персонажу, а не вообще.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.