Классовая борьба

Logik
Offline
Зарегистрирован: 05.08.2014

Arhat109-2 пишет:

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

Верно излагаеш. Добавлю тока что активная работа с указателями на функции - офигенно мощная штука.  Даже самое мощное что есть в чистых сях. Её использовоние покрывает всю виртуальность плюс еще много разного интересного дает. И походу это самое опасное. Неаккуратность валит програму как два пальца.  Вот потому вокруг него и накрутили ООП. Чтоб с одной стороны заюзать неопытными пользователями, заменив им понимание работы процессора на догмы ООП, а с другой стороны спрятав указатели в VMT более-менее обезопасить технологию. Ну а для пипла, чтоб прикрыть, что осетра им урезали, служат рассказы про более высокий уровень абстрагирования и строгое разграничение. Что и слышим. Абстрагирование - оно в голове и от неё зависит, а разграничение на модули и либки намного строже получается чем на классы.

Про экономию ресурсов и указатели на функции. Классическая машинка состояния, свитч, многоэтажные кейсы... Загоняем кейсы в функции, а их указатели в массив в PROGMEM и вместо длинючего свитча по некоторому id получаем нечто типа ArrFunc[id](). А если лямбда-функции использовать, то и лишних имен придумывать не прийдется.

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

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

Точно такжеж и тут: посмотрев и освоив С++ в свое время .. внезапно понял, что ничего, акромя "синтаксического сахара" в нем нет. Но, для новичков пугать ООП оказалось очень даже полезно... потом за 17-и лдетним перерывом оно забылось и всплыло совсем не так давно. В смысле понимание, что на Си можно писать практически ВСЁ и как на "жабаскрипт" и как ООП и много лучше. :)

(* ещё бы препроцессор допилить на предмет некоторых упущений, но и без них неплохо *)

Arhat109-2
Offline
Зарегистрирован: 24.09.2015

По поводу экономии ресурсов: никакой "уровень абстракции вверх" не позволяет этого делать. А вот "внятно" (и быстро) можно писать на чем угодно - дело привычки и культуры писателя. :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

DetSimen пишет:

DIYMAN, просвети, реально в С++ можно наследовать класс от структуры?  

А они ничем не отличаются ;) Структура - это то же самое, что

class A
{
public:
  ....
};

В структуре модификатор доступа по умолчанию ко всем членам - public. Но ничего не мешает и там разделить на private, protected и public. Короче, ключевое слово struct в C++ - это класс со всеми открытыми членами по умолчанию. Я просто юзаю их для экономия кол-ва нажатий клавиш :), когда это необходимо.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Да, спасибо, мне Евгений Петрович уже разъяснил.  Век живи, век учись. :) 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Кстати, о goto, я тут как-то уже писал о таком замечательном языке, как INTERCAL. В нём нет goto (от слова вообще). Зато там есть противоположный оператор - comefrom (получить управление из) - замечательная вещь!

Shuring
Offline
Зарегистрирован: 16.08.2018

DetSimen пишет:
спасибо, не знал.  В Delphi такова нет.

Наследовать классы (class) от структур (record) в Delphi нельзя, потому что эти типы принципиально разные, не так как в C++.

НО! Немногие знают, что в Delphi есть структуры, практически аналогичные классам C++ (за исключением ряда нюансов). Это объекты (object). Этот тип достался по наследству от Turbo Pascal, и до сих пор поддерживается в современных версиях Delphi. Есть наследование, конструкторы/деструкторы, простые и виртуальные методы. Память для экземпляра может выделяться как статически, так и динамически (классы Delphi - только динамически).

Практическая польза от object в современном коде может быть там, где требуется структурный тип, который можно наложить на любую память, но более развитый, чем record. В частности, в структурах данных при реализации протоколов удобно применять наследование:

type
  TFrameHead = object
    Sync  : byte;
    Cmd   : byte;
  end;

  TAnswer = object(TFrameHead)
    Res   : byte;
    Stat  : byte;
  end;

  TFuncRq = object(TFrameHead)
    Func  : byte;
  end;

  TDataFuncRq = object(TFuncRq)
    Pad   : byte;
    Len   : byte;
    Data  : record end;
  end;

  TClassRq = object(TFrameHead)
    Pad   : byte;
    Len   : word;
    Offs  : word;
    Code  : byte;
  end;

  TClassAns = object(TAnswer)
    Len   : byte;
    Data  : record end;
  end;

 

sadman41
Offline
Зарегистрирован: 19.10.2016

DIYMan пишет:

sadman41 пишет:

Отсюда и вопрос: выбор класса, как некоего враппера - это выбор нормальный или есть получше?

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

1. Самое то!

2. Не обязательно условную компиляцию, можно интерфейсы, типа такого:

....

В принципе я понял. Только не знаю - имеет ли смысл держать два жирных драйвера в мелком МК, если учесть тот факт, что устройства на ходу интерфейсные модули не меняют.

...и, вроде,  у них еще и какая-то междусобойная непереносимость - начинают массово ошибки компиляции валиться, если их одновременно подключать (Ethernet и UIPEthernet). А разбираться в чужом коде уровня драйвера на ENC28J60 мне не по зубам. Так что пошел простым путем.

Из всего обсуждения я понял, что выбрал не самый худший способ и потери по памяти интуитивно (т.е. наугад) можно оценить в десяток указателей.

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DIYMan пишет:

andriano пишет:

Странно это.

Я вот уже около четверти века не использую GOTO. Совсем.

И еще ни разу не понадобилось.

Ни разу не использовал с момента начала занятий программированием. Ни разу не понадобилось :)

Так до этого я 15 лет писал на Фортране!

И, кстати, с Фортраном до сих пор не распрощался. Но уже без GOTO.

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

negavoid пишет:

Да все, кто отписался, что не использует goto - ещё как используют, просто в неявном виде. Каждый if, switch/case, return - это всё goto (jz je jmp).

Отнюдь.

if, switch/case, return - это структурные операторы, а goto - это бесструктурный. На одной и той же бумаге можно написать как нетленку, так и порнографию, но это же не повод, чтобы сравнивать.

 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DetSimen пишет:

Ну я всегда знал, что интеллектом не блещу...  

Интеллект - он не для блеска. А шоб был.

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

Shuring пишет:

НО! Немногие знают, что в Delphi есть структуры, практически аналогичные классам C++ (за исключением ряда нюансов). Это объекты (object). Этот тип достался по наследству от Turbo Pascal, и до сих пор поддерживается в современных версиях Delphi. Есть наследование, конструкторы/деструкторы, простые и виртуальные методы. Память для экземпляра может выделяться как статически, так и динамически (классы Delphi - только динамически).

Я за object знаю еще со времен Turbo Vision.  Действительно, это тип - значение, как и record.  Но, я говорил про то, что в Delphi нельзя наследовать класс от record, и, если уж на то пошло, от object тоже.  Только класс от класса, Object от object-а, а record вапще не наследуется. Казёл. 

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

andriano пишет:

Интеллект - он не для блеска. А шоб был.

У меня теперь нету. 

andriano
andriano аватар
Offline
Зарегистрирован: 20.06.2015

DetSimen пишет:

Я за object знаю еще со времен Turbo Vision.  Действительно, это тип - значение, как и record.  Но, я говорил про то, что в Delphi нельзя наследовать класс от record, и, если уж на то пошло, от object тоже.  Только класс от класса, Object от object-а, а record вапще не наследуется. Казёл. 

Ну, то, что record не наследуется, это, конечно, неудобно. Но в целом отсутствие перекрестного наследования - вполне в стиле Паскаля, что, в общем-то, довольно логично.