ООП: доступ к методу класса из-вне

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: ООП: доступ к методу класса из-вне

Сообщение Лекс Айрин » 24.05.2016 13:44:17

SSerge писал(а): Кроме декорации в виде begin/end он мало чем отличается от нелюбимой "C группы",


Основное отличие в том, что переменные должны быть описаны заранее... ну и так, по мелочи. Хотя сейчас С/С++ и FPC потихонечку приближаются по синтаксису... что зело печально.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: ООП: доступ к методу класса из-вне

Сообщение debi12345 » 24.05.2016 15:50:24

он должен быть создан и к нему должен быть доступ. Иначе зачем вообще такой класс нужен ?

Например (как показано в PHP-примере с полнстью статическим классом) для создания сложного "custom data type" с возможностью его дальнейшего развития через полиморфизм.

Добавлено спустя 7 минут 31 секунду:
Основное отличие в том,

Народ, Вы чо ???! Хэдер-файлы! Дифайны vs интерфейс+имплементация !
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: ООП: доступ к методу класса из-вне

Сообщение Лекс Айрин » 24.05.2016 16:57:37

debi12345 писал(а): Хэдер-файлы!

угу... хедер, насколько я видел, аналог inc файлов... а они просто вынесенные за пределы основного файла куски. Как я понял, в сишных языках просто принято там описывать переменные и константы.

debi12345 писал(а):Дифайны


пожалуй, это единственная реально стоящая функциональность скопированная из С

debi12345 писал(а):интерфейс+имплементация !

если данная возможность не превращает текст модуля в один объект, то она по сути бесполезна. И ведь не превращает.

ЗЫ: сделать стандартный паскаль ООП языком не так уж и тяжело. Нужно просто считать, что обычные переменные и константы это объекты классов VAR и CONST. А типы это определения объектов.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: ООП: доступ к методу класса из-вне

Сообщение resident » 24.05.2016 17:32:16

debi12345 писал(а):В статический код базового класса можно вынести типо-независимые и авто-типо-приводимые алгоритмы - операции с массивами, арифметику и т.п... а типо-зависимый-оптимизированный код вынести-переопределить в классы-наследники под конкретные типы.

Можете показать на каком-нить примере, как это разделять?
resident
энтузиаст
 
Сообщения: 605
Зарегистрирован: 13.03.2013 16:58:51

Re: ООП: доступ к методу класса из-вне

Сообщение debi12345 » 24.05.2016 19:46:02

Можете показать на каком-нить примере, как это разделять?

Статический полиморфизм по типам данных ? Думаю это возможно только если эти данные принимаются как аргументы вызова (либо через generic-типы вроде TObject/Variant, либо через механизм "overload" для одноименных функций), а не хранятся внутри класса.

ПС: Мартин, автор MSE, почти всегда объявляет методы статическими если внутри них нет обращений к нестатическим элементам класса. 100% что это сделано из соображений скорости - вероятно исключаются рантайм-завязки на RTTI.

Добавлено спустя 10 минут 20 секунд:
а они просто вынесенные за пределы основного файла куски

Не совсем так. Хэдеры позволяют компилировать и отлаживать зависимые проекты без наличия полных (с имплементацией) исходников базовых проектов.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: ООП: доступ к методу класса из-вне

Сообщение Лекс Айрин » 24.05.2016 19:57:34

debi12345 писал(а):Хэдеры позволяют компилировать и отлаживать зависимые проекты без наличия полных (с имплементацией) исходников базовых проектов.


А зачем?
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 5723
Зарегистрирован: 19.02.2013 16:54:51
Откуда: Волгоград

Re: ООП: доступ к методу класса из-вне

Сообщение debi12345 » 24.05.2016 21:26:50

А зачем?

Например Вес полных исходников всего линукс-ядра (нужных для компиляции проектов, использующих API ядра) в десятки раз превышает вес хэдеров. Также можно собирать ядро-зависимые проекты под неактуальную версию ядра, если нужны объявления в хэдекрах не изменились.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 24.05.2016 21:33:12

Лекс Айрин
Правильным считается код, который имеет точно определенные реакции на определенные воздействия, без неявных побочных эффектов. Явные бывают, но считаются не рекомендуемыми.

Это скорее к программе, не к коду. Правильный код - простой, понятный и легко поддерживаемый. Его может развить, поправить и доработать кто то другой, а не только автор после долгих раздумий-воспоминаний что же в этом месте происходит))
и мне не нравятся языки С группы.

Паскаль какраз и есть С с парой плюшек, только для людей, а не для роботов))

resident
У меня всё, что относится к классу или потомкам прикрыто топовым классом, типа неймспейс. Без привязки ничего не болтается. А если надо, то вот оно - хочешь экземпляр создавай, хочешь типы и рули ими. Неверный шаг сделать просто нельзя. Это и есть структура по-моему.

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

Незнаю что имел ввиду debi12345, я имел ввиду чтото наподобии этого http://svn.freepascal.org/svn/fpc/trunk ... c/gutil.pp класс TLess (это генерик для сравнения простых типов) им специализируется TMap для сортировки ключей. Можно использовать TLess, можно подсунуть свою "сравнивалку" ее описание из http://svn.freepascal.org/svn/fpc/trunk ... rc/gmap.pp :
Код: Выделить всё
  generic TMapCompare<TPair, TKeyCompare>=class
    class function c(a,b :TPair):boolean;
  end;

,если в качестве ключа используется какойто сложный тип данных.
Пример не очень хороший, т.к. от "сравнивалки" требуется всего один метод - c(Compare). Я сейчас делаю что-то подобное для геометрических данных, там "сравнивалка" посложнее - уже нарисовалось 5 методов. Имхо очень удобный подход - имеем общий генерик описывающий структуру данных, специализируем его типом данных и классом операций над данными (которые невозможно обобщенно описать в генерике) Получается структура данных нужного типа. Класс в данном случае служит объеденяющей "областью видимости" для операций над данными и в моем случае специализация генерика будет выглядеть так:
Код: Выделить всё
TGeomBinaryTree<TGeomPrimitive,TGeomPrimitiveManipulator>

вместо
Код: Выделить всё
TGeomBinaryTree<TGeomPrimitive,TGeomPrimitiveCompareFunc1,TGeomPrimitiveCompareFunc2,TGeomPrimitiveCompareFunc3, ... ,TGeomPrimitiveMoveFunc1,TGeomPrimitiveMoveFunc2, ...>

Разве не красота и структурированность?
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение debi12345 » 24.05.2016 23:55:11

2 zub: кажется это мы с Вами гоняли разные типы контейнеров на скорость - эти тесты приаттачены. К удивлению в этих тестах победили STL и SDL(TObject)
Так что можно будет сравнить с Вашим новым типом :)
У вас нет необходимых прав для просмотра вложений в этом сообщении.
Аватара пользователя
debi12345
долгожитель
 
Сообщения: 5761
Зарегистрирован: 10.05.2006 23:41:15
Откуда: Ташкент (Узбекистан)

Re: ООП: доступ к методу класса из-вне

Сообщение скалогрыз » 25.05.2016 00:18:25

zub писал(а): Класс в данном случае служит объеденяющей "областью видимости" для операций над данными и в моем случае специализация генерика будет выглядеть так:
Код: Выделить всё
TGeomBinaryTree<TGeomPrimitive,TGeomPrimitiveManipulator>

ну а зачем в этом случае генерики? :)

я к тому, что почему бы не сделать TGeomBinaryTree обычным классом, точно так же как и TGeomPrimitiveManipulator - абстрактным и от него делать наследников с реализацией под конкретный TGeomPrimitive.
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 25.05.2016 01:00:55

debi12345
Скоростью пока не интересовался - с надежностью не всё в порядке, но fpc-stl обогнать точно не получится))
скалогрыз
Потому что на данном этапе мне нужно 2 реализации такого дерева для разных типов данных. "высокоуровневые" примитивы - те которыми оперирует пользователь и "простые" примитивы - те которыми оперирует графическая система (высокоуровневые рисуют себя низкоуровневыми). "Сливать" их вместе, делая общего предка и общие методы не нужно, это совершенно разные вещи. Хотя по законам ООП наверно так правильней))
В дальнейшем планирую от дерева для высокоуровневых примитивов отказаться запихав их обратно в линейный контейнер. Чтоб при переходе между этапами (который длится уже долго и всё никак не начнется)) ) не тащить 2 реализации дерева или одну, но без контроля типов на указателях решил заюзать генерики.
Описные выше варианты трехмерные, разделение пространства плоскостью, анализ по AABB примитивов, во влажных мечтах еще двухмерный случай (плоскость=прямая, ААББ=прямоугольник), который надеюсь получить просто другим TGeomPrimitiveManipulator
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение скалогрыз » 25.05.2016 01:14:37

zub писал(а): "Сливать" их вместе, делая общего предка и общие методы не нужно, это совершенно разные вещи. Хотя по законам ООП наверно так правильней))

Ни в коем случае.
Просто я бы думал TGeomBinaryTree был бы рабочий объект, готовый принимать что угодно, а что это именно и как с этим работать решал бы TGeomPrimitiveManipulator.

Вроде того как TList принимает что угодно, а разбирается с этим "что угодно" процедура Sort()
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: ООП: доступ к методу класса из-вне

Сообщение zub » 25.05.2016 01:28:18

>>Просто я бы думал TGeomBinaryTree был бы рабочий объект, готовый принимать что угодно,
>>а что это именно и как с этим работать решал бы TGeomPrimitiveManipulator.
С генериками так и есть, но TGeomBinaryTree<TDXFEntity,TDXFEntityManipulator> и TGeomBinaryTree<TLowLevelEntity,TLowLevelEntityManipulator> разные классы с методами отличающимися типами аргуметов = проверка типов при компиляции

>>Вроде того как TList принимает что угодно, а разбирается с этим "что угодно" процедура Sort()
это указатели и отсутствие проверки типов.

Добавлено спустя 33 минуты 1 секунду:
debi12345
Померил скорость:
zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-objects

real 0m0.696s
user 0m0.500s
sys 0m0.192s

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-pointers

real 0m0.827s
user 0m0.572s
sys 0m0.252s

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-presized

real 0m1.048s
user 0m0.744s
sys 0m0.300s

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-sdl

real 0m0.395s
user 0m0.368s
sys 0m0.024s

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$ time ./test-stl

real 0m0.217s
user 0m0.212s
sys 0m0.004s

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test$
zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test/zcontainers$ time ./testzcontainers

real 0m0.280s
user 0m0.272s
sys 0m0.004s

zamtmn@desktop:/media/zamtmn/source/hdd/algotests/algo_test/zcontainers$ time ./testzcontainers


Добавлено спустя 8 минут 45 секунд:
Проигрыш изза обертки над менеджером памяти (хочу контролировать все выделения), соответственно приходится обертывать обычный а не динамический массив - комилятор всяко инициализирует\финализирует быстрее чем я руками на основе TypeInfo. Но зато у меня сам массив открыт напрямую, а не поэлементно через геттер\сеттер - поэтому просто бегать по массиву должно быстрее.
исходник:
Код: Выделить всё
program testzcontainers;
{$mode objfpc}{$h+}

uses
  sysutils,strings,gzctnrvector;

const
  TEST_CNT = 300000;

type

  chmorec = packed record
    int_val: integer;
    str_val: pchar;
  end;
  pchmorec = ^chmorec;

  ANYTYPE = (INT_T,TEXT_T,REAL_T,CHMO_T);

  anydatarecty = packed record
    case data_type:ANYTYPE of
      INT_T:  (ival: integer);
      TEXT_T: (tval: pchar);
      REAL_T: (rval: double);
      CHMO_T: (chmoval: chmorec);
  end;
  anydatarecarty=specialize GZVector<anydatarecty>;


procedure addelem(var arr: anydatarecarty; atype:ANYTYPE; adataptr: pointer);
var
   adata:anydatarecty;
begin
  adata.data_type:= atype;
  case atype of
    INT_T: adata.ival:= integer(adataptr^);
    TEXT_T: adata.tval:= strnew(pchar(adataptr));
    REAL_T: adata.rval:= double(adataptr^);
    CHMO_T: begin
      with adata.chmoval do begin
        int_val:= (chmorec(adataptr^)).int_val;
        str_val:= strnew((chmorec(adataptr^)).str_val);
      end;
    end;
  end;
  arr.PushBackData(adata);
end;


var
arr1: anydatarecarty;
i1: integer;
pch1: pchar;
r1: double;
chmo1: chmorec;
i: integer;

begin
  //arr1:=anydatarecarty.Create;
  arr1.init(1{начальный размер 1 элемент});
  for i:= 0 to TEST_CNT do begin
    i1:= i;
    addelem(arr1,INT_T,@i1);

    r1:= double(i);
    addelem(arr1,REAL_T,@r1);

    pch1:= pchar(inttostr(i) + ' as text');
    addelem(arr1,TEXT_T,pch1);

    chmo1.int_val:= i;
    chmo1.str_val:= pchar(inttostr(i) +' as text in CHMOREC');
    addelem(arr1,CHMO_T,@chmo1);
  end;


  for i:=arr1.count-1 downto 0 do begin
    case integer(arr1.parray^[i].data_type) of
//    integer(INT_T):  writeln('int val = ',  arr1[i].ival);
      integer(TEXT_T): begin
//        writeln('text val = ', arr1[i].tval);
        dispose(arr1.parray^[i].tval);
      end;
//      integer(REAL_T): writeln('real val = ', arr1[i].rval);
      integer(CHMO_T): begin
//        writeln('chmo rec = {', arr1[i].chmoval.int_val,',',arr1[i].chmoval.str_val, '}');
        dispose(arr1.parray^[i].chmoval.str_val);
      end;
    end;
  end;
  arr1.Done;

end.

практически не отличается от test-stl, разве что arr1 это объект и не PushBack, а PushBackData
zub
долгожитель
 
Сообщения: 2887
Зарегистрирован: 14.11.2005 23:51:26

Re: ООП: доступ к методу класса из-вне

Сообщение скалогрыз » 25.05.2016 03:46:15

zub писал(а):это указатели и отсутствие проверки типов.

ну не обязательно использовать указатель, можно скажем TObject, и проверять тип в run-time, если нужно.
Но тонкость в том, что это твой алгоритм, и ты будешь уверен в тех данных, которые ты будешь обрабатывать в TGeomPrimitiveManipulator
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: ООП: доступ к методу класса из-вне

Сообщение Mirage » 25.05.2016 04:23:31

SSerge писал(а):Языки, построенные на парадигме ООП, а не на костылях процедурно-ориентированного кода, вообще не допускают создания чего либо вне системы классов.


А что в этом хорошего?

SSerge писал(а):Функция может генерить exception? А вы не хотите обрабатывать? Ну-ну. Значит должны в явном виде передать на предыдущий уровень.


На практике оборачивают в RuntimeException. В современных классах родной библиотеки сразу идет RuntimeException. Короче, идея себя не оправдала.

SSerge писал(а):Процедур вообще нет. И да, нужно определить какие-нибудь константы или функции, не привязанные к объекту - должны объявить как static и разместить в каком-нибудь классе.


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

debi12345 писал(а):кажется это мы с Вами гоняли разные типы контейнеров на скорость - эти тесты приаттачены. К удивлению в этих тестах победили STL и SDL(TObject)


Свои чтоли прикрутить к этому тесту... Там параметризация не только типом, но и функцией, например. Можно без ООП-оверхеда подсовывать, скажем, функцию сравнения словарю, или алгоритму сортировки. Жаль только код получается некрасивый в синтаксическом плане.
Mirage
энтузиаст
 
Сообщения: 881
Зарегистрирован: 06.05.2005 20:29:07
Откуда: Russia

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: Google [Bot] и гости: 250

Рейтинг@Mail.ru