Архив метки: class

Классы #3

bdr>  Прочитал твои два послания. Спасибо за информацию.
bdr>  У меня к тебе два вопроса, если есть время.
bdr>  1. Чем все таки лучше и правильно ли использовать
bdr>  Init       PROCEDURE(*GROUP _objB)
bdr>   или как приводил Андрей передавать адрес класса в STRING
bdr>   и почему неиспользовать
bdr>   Init       PROCEDURE(ClassB _objB)

Как внес поправку Андрей — передавать адрес через строку удобнее при запуске нового потока. Так как только строки возможно передавать в качестве параметров. При обычном вызове — лучше передавать через группу, т.к. — это «родной» формат для класса. Использовать в качестве параметра класс — тоже правильно. Другое дело, что при таком описании ты не сможешь в эту процедуру передать другой класс. А при передаче через строку или группу можно передавать любые классы.

bdr>  2.Второй вопрос несколько на другую тему, но о классах
bdr>  Описаны 3 типа класса: класс А; и В и С порожденные от А
bdr>  В некую процедуру(это может быть и метод вообще другого класса)
bdr>  в качестве параметра передаются класс типа В или С
bdr>   ( Procedure(ClassA CurrentClass)). Как в этой процедуре определить
bdr>  что передан класс типа В или класс типа С, неспользуя дополнительных
bdr> параметров.  В DELPHY для этого есть AS.

Два способа:

я иногда завожу в классах строковую переменную, в которую при инициализации записываю название типа класса.

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

Есть, правда, еще один способ. Посложнее. Класс передается в процедуру по адресу его буфера. Первым лонгом в этом буфере идет адрес таблицы виртуальных методов. Вот уже он — разный для разных классов. Он назначается на этапе компиляции. Так что, в принципе, в начале программы можно составить некую таблицу этих адресов VMT для разных классов и уже по ней идентифицировать классы. Кстати, если у класса нет виртуальных методов или вообще нет методов — все равно этот параметр есть. Он используется RTL-библиотекой для получения полной инфы о структуре класса. Эта инфа записана непосредственно ПЕРЕД тем адресом, на который указывает адрес VMT.

Классы #2

bdr> <.. не с потолка же я взял этот механизм ..
bdr>  А можно поинтересовать как ты к этому пришел.
bdr>  Мне лично не понятно как вообще компилятор это пропускает.
bdr>  Ведь в STRING может и не лежать адрес класса, а приведение к указателю
bdr> класса неизвестно чего

А это уже твои проблемы! Я когда-то уже писал, в Кларионе можно сделать очень много разных нестандартных вещей. Практически как в С. Но и ответственность за неправильное их использование ложиться уже на программиста.

bdr>  должно отлавливаться компилятором.
bdr>  Это что глюк или «расширение» возможностей клариона.

Это — обычное поведение компилятора. Конструкцию типа:

Ref &= (Var)

компилятор воспринимает как приведение к лонгу и уже этот лонг принимает за обычный адрес.

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

А чего надо?:)

Классы

bdr>  Если первый пример мне понятен, то со вторым:
bdr> <Ещё, Если Вы хотите загружать динамически какие то библиотеки то не
bdr> <используёте LoalLibrary, а используйте Cla$LoadLibrary, прототипы те-же

Угу. Только чуточку по другому:

  MAP
    LoadLib(LONG _LibNameAddr),LONG,NAME('Clw$LoadLibrary')
  END

_LibNameAddr — адрес строки CSTRING с именем библиотеки.

bdr> А можно хоть небольшой комментарий.
bdr> Что это дает?
bdr> Александр Бирюков

По большому счету, эта — простая надстройка над API-шной LoadLibrary:

  • сохраняет регистры CX,DX
  • забрасывает адрес строки из AX в стек
  • вызывает LoadLibraryA
  • востанавливает DX,CX
  • возвращает AX

По своему опыту общения с Кларионом на низком уровне могу сказать, что Кларион ОЧЕНЬ чувствителен к регистрам. Поэтому, когда идет вызов ЛЮБОЙ процедуры, компилятор предполагает, что после возврата из этой процедуры все основные регистры (BX,CX,DX,SI,DI) имеют тоже значение, что и до вызова. Не «закладывается» компилятор только на AX, и то, только для функций, которые возвращают результат через AX.

Я таким образом уже несколько раз «влетал» со своими asm-процедурами. Пока не стал сохранять/восстанавливать регистры, постоянно «лезли» какие-то левые глюки.  Удалось «вычислить» только после кропотливого анализа сбойного участка с откатом назад, до места-источника проблем.

В принципе, компилятор должен учитывать, что процедуры с атрибутами C или PASCAL могут иметь другое поведение по отношению к регистрам. Но, очевидно, иногда где-то он все-таки «прокалывается» или вообще не принимает этого в расчет.

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

Некоторые особенности при работе с CLASS`ами

Я думаю многие обрадуются, если я сообщу, что есть возможность работать с любыми переменными любых классов!
Независимо от атрибута Private или Protected!

Особенно это актуально при работе с ABC-шаблонами, чьи классы организованы не самым лучшим образом! Теперь, для доступа к Private-переменным, нет необходимости в модификации исходников.

Все очень просто решается использованием функций What/Who/Where! Читать далее

VIRTUAL — определение виртуальных методов

Переведен стандартный раздел помощи для ключевого слова «VIRTUAL». Рекомендуется к прочтению.
Атрибут VIRTUAL — это атрибут, используемый при описании прототипа метода класса. Определяет, что процедура будет являться виртуальным методом класса.
Это позволяет методам РОДИТЕЛЬСКОГО класса вызывать методы ДОЧЕРНЕГО класса. Атрибут VIRTUAL должен быть объявлен
в обоих прототипах методов: и в родительском и в дочернем классе. Читать далее

В первый класс

Мнение о том каким должен быть «настоящий» класс. Этапы разработки класса. В этой статье я изложу свое мнение о том, каким должен быть настоящий класс, от и до.

Перед прочтением желательно прочитать help по ключевому слову CLASS. Если в процессе чтения вам встретятся незнакомые операторы, команды, ключевые слова — читайте также help и по ним в стандартной помощи Клариона — F1.

Не так давно я в который раз получил задание на создание отчета вида: товар, цена, количество, сумма без НДС, сумма НДС, сумма. Последние три поля являются расчетными.
И мне опять пришлось вспоминать, а вернее выводить формулу для расчета НДС. Расчет НДС можно производить разными путями Читать далее

CLASS — определение класса в Clarion

Переведен стандартный раздел помощи для ключевого слова «CLASS». Рекомендуется к прочтению.
Описание класса:

label CLASS([parentclass])[,EXTERNAL] [,IMPLEMENTS] [,DLL] [,STATIC] [,THREAD]
           [,BINDABLE] [,MODULE( )] [, LINK( )] [, TYPE]
                     [ data members and methods ]
      END

Читать далее

ООП…рулит

Cерия статей простым и доступным языком рассказывает о использовании ООП применительно к базам данных.

По мере надобности можно дописать отчеты, в которых появилась необходимость. В некоторой точке вы начинаете писать код, который уже встречался в другом отчете. Код не одинаков «один в один», но имеет похожую логику. И однажды, вы понимаете, что имеете три разных отчета представляющих одни и те же данные в разных видах. Это является проблемой. Например, при изменении данных в таблице, вы будете вынуждены модифицировать три процедуры отчета и изменить три секции кода. При большом количестве процедур это настоящая проблема, можно что-то легко забыть или пропустить.

Сейчас есть лучшее решение такой задачи: ООП. Читать далее