Re[2]: Большой минус С++
От: _NN_ www.nemerleweb.com
Дата: 25.12.21 10:13
Оценка:
Здравствуйте, Sm0ke, Вы писали:

S>Есть ещё виртуальные методы. При оверрайде их в классах наследниках приходится повторно прописывать те же аргументы по несколько раз. И при изменении в базовом классе тянуть все изменения везде. Более того это не обязательно должны быть именно виртуальные методы. В моём одном проекте есть набор классов, имеющих набор статических методов с одинаковым именем и прототипом. В этом случае приходится пользоваться поиском-заменой — и я считаю это уже "гемор".


Откройте для себя IDE и инструменты рефакторинга.
Скажем Visual Studio, Resharper C++, CLion, и т.д.
Одним щелчком меняются сигнатуры всех наследников.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[4]: Большой минус C#
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 25.12.21 10:17
Оценка:
Здравствуйте, Marty, Вы писали:

MA>>>Открываешь файл — там класс на 1K+ строчек, и понять, что вообще там за методы или свойства есть — никакого способа нет, кроме как исследовать код через IDE (при чём во всех это сделано через неудобно).


У C++ практически та же проблема при большом количестве inline методов, определённых внутри класса.
Выносить эти определения отдельно... можно, конечно, поставить такое стилевое условие, но может быть жестковато.

SP>>в студии Ctrl M + O Collapse To Definitions. Получаем просто h файл.


M>Когда ты зашел по SSH и запустил 'nano'


nano сношу везде, где всерьёз работаю, и ставлю joe. А у него уже есть Ctrl+G для поиска парной скобки.
Ну и разумеется vim ('%' для того же действия).
Это уже кое-что — хотя придётся попрыгать по всем методам.

Вообще для решения таких задач без IDE придуманы всякие ctags, etags... они делают список, который можно просто просмотреть глазами, а можно в редакторе подключать и использовать для позиционирования на нужную функцию (метод). Внутрь классов и неймспейсов они давно научились заглядывать.
The God is real, unless declared integer.
Re[4]: Большой минус C#
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 25.12.21 10:23
Оценка:
Здравствуйте, Mystic Artifact, Вы писали:

MA> Публичный контракт из C# или Java получить совершенно точно не представляется возможным, пока вы не выполните работу компилятора.


Хм, как правило в этих обоих языках _публичный_ контракт выделяют в виде сущности типа interface. По крайней мере так ну очень рекомендуется. А уже отнаследоваться от интерфейса — сделать реализацию — можно и только на нужные методы.

Конечно, никто не заставляет так делать, и внутри пакетов на это поплёвывают.

(А ведь интерфейсы, в этом смысле, и есть аналоги заголовочников C/C++.)

MA> В реальности — в проектах — есть одна директория куда навалено по заветам FDG — т.е. все в одну кучу,


Реально есть такой завет?

MA> и если вы это видите все в первый десяток раз — то никакие средства IDE — не помогут, не говоря уже о том, что IDE нужна когда нужна но не более. А если код логически расформирован — то внезапно уже и IDE не нужна что бы понять что и где.


Ну при определённом уровне сложности с IDE таки в разы легче

MA> А если есть публичные хидеры — то вообще знакомство происходит не с основания горы с миллионом незначащих подробностей — а с вершины.


MA> Я собственно говоря, не топлю ни за один ни за другой способ. Просто вижу преимущества и первого и второго. Преимущества второго (наличия хидеров) для меня открылись только в последние <10 лет. А 20 лет назад я был восхищен тем, что в C# нп нужно писать эти дурацкие хидеры.


Я конечно извиняюсь, и не придирка, но: https://dictionary.cambridge.org/dictionary/english/header

header
UK /ˈhed.ər/
US /ˈhed.ɚ/

Ну нету там "и".
The God is real, unless declared integer.
Re[8]: Большой минус С++
От: T4r4sB Россия  
Дата: 25.12.21 10:30
Оценка: +2
Здравствуйте, Marty, Вы писали:

M>Но вообще — какие-то через-чур наивные вопросы, от человека, который сто лет тут обитает и пишет на плюсах


Можно испускать негатив в адрес Страуструпа, Степанова, Александреску, всего сообщества крестовиков в целом, но ты его направляешь именно на конкретных людей, причём без предварительного наезда с их стороны.
Отредактировано 25.12.2021 10:30 T4r4sB . Предыдущая версия .
Re[5]: Большой минус C#
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 25.12.21 10:47
Оценка:
Здравствуйте, netch80, Вы писали:


N>Я конечно извиняюсь, и не придирка, но: https://dictionary.cambridge.org/dictionary/english/header


N>header

N>UK /ˈhed.ər/
N>US /ˈhed.ɚ/

N>Ну нету там "и".


И нас много
Маньяк Робокряк колесит по городу
Re[6]: Большой минус С++
От: maks1180  
Дата: 25.12.21 11:03
Оценка:
M>По любому, один из классов будет только ссылаться на другой, ссылка или указатель — это уже детали. Более того, я чего-то сомневаюсь, что в каком-либо языке такое вообще возможно


Ты себя крутым считаешь, всех хаишь — сам бред полный написал. Такое невозможно скомпилировать, так возникает бесконечная вложенность в данных.
Я вот что имеел ввиду:

class B;

class A {
public:
void DoSomething() {
m_v = B::GetV();
}
private:
int m_v;
};

class B {
public:
static int GetV() { return 1; }
void DoSomething() {
A a; a.DoSomething();
}
};
===============================================
(реклама, удалена модератором)
Отредактировано 25.12.2021 11:04 maks1180 . Предыдущая версия .
Пример кода
От: maks1180  
Дата: 25.12.21 11:13
Оценка:
Вот такой код не получается скомпилировать, если не выносить функции в другой файл. На строку "m_v = B::GetV()" gcc ругается.
Хотя я не понимают, почему gcc не хочет в 2 этапа это сделать:
1) сначала пробежаться и составить объявления всех классов и функций
2) скомпилировать функции

class B;

class A {
public:
void DoSomething() {
m_v = B::GetV();
}
private:
int m_v;
};

class B {
public:
static int GetV() { return 1; }
void Do() {
A a; a.DoSomething();
}
};

Может я что-то не понимаю ?
===============================================
(реклама, удалена модератором)
Отредактировано 25.12.2021 11:15 maks1180 . Предыдущая версия .
Re[2]: Большой минус С++
От: maks1180  
Дата: 25.12.21 11:17
Оценка:
V>Вообще это плюс. В хидере у тебя интерфейс, в сишнике имплементация.

Да, только все современные языки такие как C#, Java ушли от этого "так называемого плюса".
===============================================
(реклама, удалена модератором)
Re[7]: Большой минус С++
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 25.12.21 11:34
Оценка: -1
Здравствуйте, maks1180, Вы писали:

M>>По любому, один из классов будет только ссылаться на другой, ссылка или указатель — это уже детали. Более того, я чего-то сомневаюсь, что в каком-либо языке такое вообще возможно



M>Ты себя крутым считаешь, всех хаишь — сам бред полный написал. Такое невозможно скомпилировать, так возникает бесконечная вложенность в данных.


Ты еще и читать не умеешь


M>Я вот что имеел ввиду:


M>
M>class B;

M>class A {
M>public:
M>    void DoSomething() {
M>        m_v = B::GetV();
M>    }    
M>private:
M>    int m_v;
M>};

M>class B {
M>public:    
M>    static int GetV() { return 1; }
M>    void DoSomething() {
M>        A a; a.DoSomething();
M>    }    
M>};
M>



И в чем проблема? Описал отдельно классы, сделал реализацию. Тут вообще нет никаких проблем
Маньяк Робокряк колесит по городу
Re[3]: Большой минус С++
От: rudzuk  
Дата: 25.12.21 12:31
Оценка: +2 :)
Здравствуйте, maks1180, Вы писали:

m> V>Вообще это плюс. В хидере у тебя интерфейс, в сишнике имплементация.


m> Да, только все современные языки такие как C#, Java ушли от этого "так называемого плюса".


Миллионы мух не могут ошибаться!
avalon/3.0.0
Re[8]: Большой минус С++
От: netch80 Украина http://netch80.dreamwidth.org/
Дата: 25.12.21 12:43
Оценка:
Здравствуйте, Marty, Вы писали:

M>И в чем проблема? Описал отдельно классы, сделал реализацию. Тут вообще нет никаких проблем


Ну вот вынесеш ты тело метода отдельно — будет одна проблема читать (объявление отдельно, определение отдельно, причём в этом примере после объявлений обоих классов A и B).
Нет — будет другая (слишком много определений в основном предложении class).
Что так плохо, что так плохо.
Потому и говорят, что сворачивание в IDE тут самое полезное. Но и в нём нужны переходы из объявления к телу и наоборот.
The God is real, unless declared integer.
Re: Пример кода
От: kov_serg Россия  
Дата: 25.12.21 13:07
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Вот такой код не получается скомпилировать, если не выносить функции в другой файл. На строку "m_v = B::GetV()" gcc ругается.

M>Хотя я не понимают, почему gcc не хочет в 2 этапа это сделать:
M>1) сначала пробежаться и составить объявления всех классов и функций
M>2) скомпилировать функции
a)
class B;

class A {
public:
    void DoSomething();
private:
    int m_v;
};

class B {
public:
    static int GetV() { return 1; }
    void Do() {
        A a; a.DoSomething();
    }
};

void A::DoSomething() {
    m_v = B::GetV();
}

b)
struct B0 {
    static int GetV() { return 1; }
};

struct A {
    void DoSomething() {
        m_v = B0::GetV();
    }
private:
    int m_v;
};

struct B : B0 {
    void Do() {
        A a; a.DoSomething();
    }
};


M>Может я что-то не понимаю ?

Возможно стоит вопрос сформулировать точнее. Что именно вас не устраивает?
Re: Пример кода
От: _NN_ www.nemerleweb.com
Дата: 25.12.21 13:12
Оценка:
Здравствуйте, maks1180, Вы писали:


M>Может я что-то не понимаю ?


Порядок объявлений принципиален:

void f(long){}

void g(){
f(1) вызовет f(long)
}

void f(int){} добавляем перегрузку

void h(){
f(1) теперь будет f(int)
}
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re: Пример кода
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 25.12.21 13:18
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Вот такой код не получается скомпилировать, если не выносить функции в другой файл. На строку "m_v = B::GetV()" gcc ругается.

M>Хотя я не понимают, почему gcc не хочет в 2 этапа это сделать:
M>1) сначала пробежаться и составить объявления всех классов и функций
M>2) скомпилировать функции

M>Может я что-то не понимаю ?


Ты можешь сделать метод inline'ом. Для этого не обязательно помещает его реализацию внутрь класса.
Маньяк Робокряк колесит по городу
Re[8]: Большой минус С++
От: Vzhyk2  
Дата: 25.12.21 13:48
Оценка:
M>Так — можно. И?
M>Ну вот вообще никак.
Re[9]: Большой минус С++
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 25.12.21 13:52
Оценка:
Здравствуйте, Vzhyk2, Вы писали:

M>>Так — можно. И?

M>>Ну вот вообще никак.


Это не так, про что я говорил, что никак не сделать
Маньяк Робокряк колесит по городу
Re[3]: Большой минус С++
От: Vzhyk2  
Дата: 25.12.21 13:52
Оценка:
M>Да, только все современные языки такие как C#, Java ушли от этого "так называемого плюса".
Ты еще про современный жабаскрипт забыл и еще кучу модного смузихлебного.
В отличие от всего этого модного С и С++ хотя бы логичны и последовательны.
Re: Большой минус С++
От: fk0 Россия https://fk0.name
Дата: 25.12.21 14:41
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Для меня основной минус с++ от которого хотелось бы избавиться — это дублирование кода.

M>Приходиться одно и тоже писать (название функций) в h и в cpp файлах. И менять тоже нужно в двух местах.

Проблема C++ в том, что да, если кто-то планирует выделять память для класса, то
должен видеть полное его определение. Вот это серьёзная проблема.

Ещё в C++ трудно, неудобно делать PIMPL-идиому, т.к. либо получается фабрика классов,
либо все потроха класса и, главное, все зависимости выезжают в заголовочный файл.

M>1) я пробовал писать всё в h файле (т.е. и тело функций), но тогда возникают проблемы:

M>1.1 — если класс A использует класс B и класс B использует класс A — что очень часто бывает в больших проектах. Тогда приходится некоторые функции выносить в cpp.

Не нужно. Нужно сделать forward declaration для класса и лучше вообще
писать код так, что не A использует B, а что A использует некую абстракцию
которой в итоге удовлетворяет B, но A про B ничего непосредственно не знает,
и наоборот, B про A, а только про необходимую абстракцию. Тогда абстракции
могут быть предварительно декларированы и могут быть начаты использованы
без знания о самих A или B.

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

Главное при работе с C++ -- это изменить своё мышление. C++ имеет другие методы
решения задач, чем языки вроде Java, Delphi, C#. Методы не существующие в этих языках.
А подходы применимые в других языках хоть в C++ и работают, но выглядят часто хуже.

И не нужно программу на C++ превращать в программу на FORTRAN, где всё впихнуто
в один мега-класс зависящий абсолютно от всего чего только возможно. Не нужно
стесняться разделять логику на множество простых абстракций с простыми и минимальными
зависисмостями. Такие абстракции просты, легко проверяемы, в них трудно допустить ошибку.
Их можно отдельно и независимо протестировать. А мегакласс -- это типичный спагетти-код
со всеми его "преимуществами".

При работе с шаблонами нужно не забывать, что не обязательно всё должно попасть в
заголовочмный файл, иногда можно пользоваться extern template.

M>1.2 — проблемы с #define, т.е. если #define определён в cpp после #include, он действует только в одном cpp (обычно один файл cpp = один класс). Если определить #define в h, он будет действовать на все классы которые включены после данного файла.


Честно говоря, пять раз перечитал, но не понял. C-препроцессор во-первых в современном
C++ практически не стоит использовать вообще, всё то же самое, только лучше делается
через декларативное программирование в пространстве типов, с помощью шаблонов.

Во-вторых C-препроцессор это по сути императивный язык программирования, и конечно
там порядок определений важен. Так и должно быть.

M>Может быть данные проблемы уже как-то решены, но я об этом не знаю ?


Да нет на самом деле никакой проблемы...

M>Если нет, может сделать предкомпилятор, который из одного файла (где объявление и реализация) создаст 2 файла h+cpp, которые будут компилироваться.


Модули в C++20, но вряд ли оно сильно чем-то поможет.
Re[3]: Большой минус С++
От: fk0 Россия https://fk0.name
Дата: 25.12.21 14:45
Оценка: +1
Здравствуйте, maks1180, Вы писали:

M>>Современные IDE умеют одним кликом мышки заводить новые классы, добавлять новые функции и члены класса сразу и в хедерах и в исходниках. Так же переименовывать сразу во всех исходниках (у них это в разделе "Рефакторинг" в выпадающем меню)


M>Это да:

M>1) часто на сервере нужно править исходники. Там только текстовый терминал.

Это ж замечательно, что там текстовый терминал. Значи там работает лучший
в мире редактор Vim, в котором быстро всё можно сделать. Ну или Emacs если
кому-то Vim претит.

Что было б лучше, если б там был только графический терминал и запускалась
студия? Ужас нахер, в страшном сне только такое приснится.

M>2) современные IDE, часто имеет проблемы если использовать макросы или шаблоны.


Это проблема "современынх IDE", а не макросов или шаблонов. В Vim никаких с этим проблем.

M>4) И намного удобнее когда 1 файл = 1 класс.


Когда есть много классов на пять строчек -- уже неудобно. Тогда лучше файл
как-то по имени подсистемы, компонента, неймспейса назвать и в него всё сложить.
Re[5]: Большой минус С++
От: fk0 Россия https://fk0.name
Дата: 25.12.21 14:48
Оценка:
Здравствуйте, maks1180, Вы писали:

M>Я же написал.

M>1.1 — если класс A использует класс B и класс B использует класс A — что очень часто бывает в больших проектах. Тогда приходится некоторые функции выносить в cpp.
M>С class forward declarations ты только через ссылки или указатели класс сможешь использовать, что не всегда приемлемо.
M>С одним cpp будет поностью компилиться весь проект при любом изменении!

https://en.wikipedia.org/wiki/Dependency_inversion_principle
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.