вот какой вопрос возник(словами не получается попробую на примере) дано 3 объекта(одного типа M с двумя полями- днем и месецем.) необходимо прочитать данные для первых 2-х объектов(это я сам сделаю) и ввести разницу дат в 3-ий объект(как).
примечание первый и второй объект являются родительскими для третьего. Помогите.. Собственно у меня все получается кроме обработки данных
интересно было бы увидеть реализацию и на TP.
volvo
22.04.2007 20:47
Цитата
первый и второй объект являются родительскими для третьего.
Вот с этого места - подробнее... Это как понимать? ОБА сразу? Или тип, к которому относятся И первый И второй объекты (то, есть, они принадлежат к одному типу) - родительский для типа третьего?
Цитата
Собственно у меня все получается кроме обработки данных
Описания типов - в студию...
compiler
22.04.2007 20:59
Цитата(volvo @ 22.04.2007 16:47)
Вот с этого места - подробнее... Это как понимать? ОБА сразу? Или тип, к которому относятся И первый И второй объекты (то, есть, они принадлежат к одному типу) - родительский для типа третьего?
или
Цитата(volvo @ 22.04.2007 16:47)
Описания типов - в студию...
fraction = object num, den:integer;
constructor init; procedure reduction; end;
FrRes =object(fraction) procedure print; end; {...методы...} var f1, f2:fraction; FRes:FrRes;
2 мисс_граффити ,наверно то но как собственно вызывать эту процедуру?(+ както она у меня не работает на FP)
2 volvo , спасибо за приглашение но без твоих комментариев мне будет не легко... (зачем собственно деректива в первой строчке? остальное вроде понял..) наследование было по двум причинам 1 потому что первые две дроби печатать не надо.. 2 что б было (в смысле в учебных целях)
мисс_граффити
22.04.2007 21:29
1. эта цель - она не цель разве обязательно использовать ВСЕ методы, которые есть?
2. так и думала...
Цитата
наверно то но как собственно вызывать эту процедуру?
как задать константу у обьекта/класса? заранее благодарен.
volvo
23.06.2007 23:01
Зачем это тебе, расскажи ...
мисс_граффити
23.06.2007 23:34
Разработчики Java так любят делать, по-моему. Определили в классе Double константы +бесконечность и -бесконечность, например...
hardcase
24.06.2007 1:24
Константы? Насколько я знаю такие экземпляры классов называются синглтоны. Нужно завести статическое поле/свойство в классе и при чтении возвращать объект, который создается единственный раз при инициализации класса (в нашем случае юнита, где находится класс).
volvo
24.06.2007 3:47
Цитата
Нужно завести статическое поле/свойство в классе
Можно код для FPC? (вопрос был именно про FPC, так что все сотрясания воздуха о своей крутизне в C#/Java/... можешь оставить при себе для более подходящих случаев )
hardcase
24.06.2007 4:44
Цитата(volvo @ 24.06.2007 0:47)
Можно код для FPC? (вопрос был именно про FPC, так что все сотрясания воздуха о своей крутизне в C#/Java/... можешь оставить при себе для более подходящих случаев )
Возможно вот так....
Код
interface
TMyClass = class private class function GetSingletonObject: TMyClass; public class property SingletonObject: TMyClass read GetSingletonObject; end;
implemetation
var _SingletonObject: TMyClass;
class function TMyClass.GetSingletonObject: TMyClass; begin Result := _SingleTonObject; end;
мне надо реализовать карту как обьект при этом мне могут понадобится границы... хотя наверное и не понадобится... или понадобится ну а потом для общего развития.
Добавлено через 1 мин.
Цитата(hardcase @ 24.06.2007 0:44)
Возможно вот так....
а можно комментарии...
volvo
24.06.2007 23:01
В FPC нет понятия class property... Функция/процедура есть, а свойства - нет... Так что как минимум:
type TMyClass = class private class function GetSingletonObject: TMyClass; public property SingletonObject: TMyClass read GetSingletonObject; end;
кстати, кто мне объяснит, к поставленной задаче, каким боком вообще относится синглтон? Кто-то просил объект, число экземпляров которого ограничено одним (это - синглтон)? Я не заметил этого...
compiler, константы не могут описываться внутри класса... Описывай их в Implementation-части модуля, а для обращения к ним - используй class function...
compiler
24.06.2007 23:04
я чего то туплю.... ничего не понимаю...
volvo
24.06.2007 23:19
Что непонятно? Ну, вот, скажем:
unit z;
interface
type T = class private function GetMaxSize: integer; public property maxSize: integer read GetMaxSize; end;
implementation
const the_max_size = 20;
function T.GetMaxSize: integer; begin result := the_max_size; end;
end.
uses z;
var obj: T;
begin obj := T.create; writeln(obj.maxSize); end.
Что будет напечатано?
А теперь попробуй получить доступ к the_max_size НЕ через maxSize... То есть, эффект совершенно аналогичен тому, как если бы константа была описана в самом классе...
compiler
24.06.2007 23:31
кажется понял, спасибо...
с меня +
Добавлено через 3 мин. и еще вопрос... можно ли для класса описать сравнение с нулем?
volvo
25.06.2007 2:01
Цитата
можно ли для класса описать сравнение с нулем?
Это смотря что ты хочешь сравнивать с нулем... То есть, что (для твоего класса) значит равенство нулю?
Для объекта можно было бы также переопределить "operator =", сравнивающий экземпляр объекта с целым числом, например... Для классов перегрузка операций проблематична.
мисс_граффити
25.06.2007 2:01
сорри, FPC у меня нет, проверить могу только в делфи. но идея, наверное, понятна:
T=class a,b: integer; function isNull: boolean; end; ... function T.isNull: boolean; begin isNull:=(a=0)and(b=0); end;
compiler
25.06.2007 15:22
через метод не так интересно... интересно было бы именно перегрузкой операторов... что б можна было скажем написать
...if a<>0 then ...
, где а -- пользовательский тип, имеющий два поля целых чисел, и равнявшийся нулю, если оба поля равны нулю...
volvo
25.06.2007 18:08
В таком случае (если у тебя 2 поля должны быть одновременно нулевыми чтобы объект считался нулевым) тебе лучше перегрузить оператор not:
operator not (const X: T): boolean; begin result := (X.a = 0) and (X.b = 0); end;
constructor T.init(va: integer; vb: integer); begin a := va; b := vb; end;
var obj: T; begin obj.init(); writeln(not obj);
obj.a := 9; writeln(not obj); end.
compiler
25.06.2007 18:23
Цитата(volvo @ 25.06.2007 14:08)
В таком случае (если у тебя 2 поля должны быть одновременно нулевыми чтобы объект считался нулевым) тебе лучше перегрузить оператор not...
идея интересная, но мне понадобится сравнивать и с другими числами(по крайней мере еще с одним)...
Цитата
Для классов перегрузка операций проблематична.
а где про нее можна прочитать?
volvo
25.06.2007 19:55
Цитата
идея интересная, но мне понадобится сравнивать и с другими числами
Ты бы уточнял, ЧЕГО ты хочешь? Либо КАЖДОЕ поле сравнивать с ОДНИМ И ТЕМ ЖЕ числом (тогда - вот так:
operator = (const X: T; const i: integer): boolean; begin result := (X.a = i) and (X.b = i); end; ... // тестируем: obj.init(3, 3); writeln(obj = 3);
obj.a := 9; writeln(obj = 9); ...
)
, либо (что в конце концов тебе выяснится, тебе и было нужно) каждое поле - с РАЗНЫМ числом...
Цитата
а где про нее можна прочитать?
Нигде нельзя... Попробуй то же самое сделать для Class-а, а не для Object-а, получишь ошибку компиляции... Для Object-ов и Record-ов все прекрасно работает...
compiler
27.06.2007 20:53
Цитата(volvo @ 25.06.2007 15:55)
Либо КАЖДОЕ поле сравнивать с ОДНИМ И ТЕМ ЖЕ числом, либо (что в конце концов тебе выяснится, тебе и было нужно) каждое поле - с РАЗНЫМ числом...
пока достаточно с одним...
посижу подумаю...
compiler
2.07.2007 17:47
Добрый день! У меня есть вопрос, мне надо перегрузить оператор присваивания... у меня он должен заключаться в следующем 1) присваивания между обьектами одного класса происходит стандартно(выражение слева приобретает выражение справа) 2) возможно когда выражение справа есть некий символ (а еще лучше если можно было бы использовать строку) тоесть есть класс направление (содержащий два поля -- x, y.). если я пишу
direction:='left';
, тогда должно происходить следующее
direction.x:= -1; direction.y:=0;
. Заранее благодарен.
Добавлено через 3 мин. и еще, нельзя ли использовать различные методы сравнения(в смысле перезагруженные операторы сравнения) в зависимости от передаваемых параметров?
volvo
2.07.2007 23:16
{$mode objfpc} type dir = (left, right, up, dn); T = object x, y: integer; procedure print; end;
operator := (const d: dir): T; begin with result do begin x := p[d].px; y := p[d].py; end; end;
operator := (const s: string): T; var i: dir; begin result.x := 0; result.y := 0;
for i := low(dir) to high(dir) do if p[i].s = s then with result do begin x := p[i].px; y := p[i].py; end;
end;
var x: T;
begin x := 'left'; x.print;
x := 'right'; // <--- Здесь - работаешь со строкой x.print;
x := up; // <--- А тут - с перечислимым типом x.print; end.
Цитата
нельзя ли использовать различные методы сравнения(в смысле перезагруженные операторы сравнения) в зависимости от передаваемых параметров?
Можно, только для этого должны перегружаться операторы для сравнения данных разных типов... Например, так:
// Тут твой тип будет сравниваться с целым числом operator < (x: T; i: integer): boolean; begin // ... end; // А тут - со вторым значением такого же типа operator < (x: T; i: T): boolean; begin // ... end;
compiler
4.07.2007 21:34
Огромное спасибо! но у меня есть пару вопросов, может некоторые прямо не касающееся темы...
Цитата(volvo @ 2.07.2007 19:16)
type dir = (left, right, up, dn); // ? dir это множество? T = object x, y: integer; procedure print; end;
const p: array[dir] of record//??? s: string; px, py: integer; end = //? ( (s:'left' ; px:-1; py: 0), (s:'right'; px: 1; py: 0), (s:'up' ; px: 0; py:-1), (s:'dn' ; px: 0; py: 1) ); оperator := (const d: dir): T; //вот это здорово! //а то я делал по аналогии со сравнением, //приходилось описывать возращаемый результат //и 2 получаемых(правильный термин?)...
еще раз спасибо!
volvo
4.07.2007 21:55
1.
Цитата
dir это множество?
Нет, это перечислимый тип.
2. Непонятен способ описания константы? Смотри, есть 2 способа. Можно сделать так:
type myrec = record // сначала опишем саму структуру (вернее, ее тип) s: string; px, py: integer; end; const p: array[dir] of myrec = ... // Описываем массив из этих структур
Но ведь, если мне больше нигде не нужно описание типа myrec (ну не собираюсь я его использовать больше в программе), то я могу определить этот тип прямо в описании константы. И теперь вступает в силу вот такое ограничение: я собственно тип "запись" нигде использовать не могу (поскольку он безымянный), а обращаться к полям записи через элемент массива - пожалуйста. Что и делается...
А array[dir] - собственно, создается массив такой длины, сколько элементов существует в перечислимом типе dir... То есть, приведенное выше объявление эквивалентно:
const p: array[low(dir) .. high(dir)] of record ...
или даже
const p: array[left .. dn] of record ...
Но я бы все-таки не рекомендовал пользоваться последним описанием, очень велика вероятность нарваться на ошибку, которую при первом описании ты не совершишь никогда (она будет поймана еще на этапе компиляции).
compiler
4.07.2007 22:06
Цитата(volvo @ 4.07.2007 17:55)
1. Нет, это перечислимый тип.
а где про него можна почитать? И чем он отличается от множества?
Ну, допустим, тем что множество - это набор значений некоего базового типа, а перечислимый тип определяет совершенно новый тип, никак не связанный ни с одним из уже существующих...
compiler
4.07.2007 22:32
с горем пополам вроде понл
Цитата(volvo @ 4.07.2007 18:11)
совершенно новый тип, никак не связанный ни с одним из уже существующих...
а вот это заинтересовало... можем ли мы с нуля создать свой integer
volvo
4.07.2007 22:45
Нет... Во всяком случае - с помощью перечислимых типов - нет. Элементы таких типов должны быть правильными идентификаторами, а ты хочешь, чтобы тип содержал числа, так? Число правильным идентификатором не является.
Кроме всего прочего есть ограничение на размер перечислимых типов - 256 элементов. Integer побольше будет, я думаю...
compiler
4.07.2007 23:05
а вообще возможно ли такое реализовать(именно с нуля)?
volvo
4.07.2007 23:20
А зачем? У тебя же есть уже Integer, зачем второй тебе? Ладно бы, задумал реализовать Int256 или Int1024, например, чтоб с длинными числами работать (кстати, уже было на форуме. Как-то для Aelita я делал подобную реализацию Int256)... Можно, например, реализовать так же, как в "Длинной арифметике", только ограничить количество элементов массива.
Перегрузка операций есть, значит, с переводом (строка -> число) и (число -> строка) проблем не будет. Сравнение элементов нового типа - тоже не проблема... Все реализуемо...
compiler
4.07.2007 23:26
Цитата(volvo @ 4.07.2007 19:20)
А зачем?
когда-то хотел ради интереса, но практического применения не нашел... хотя нет, если я захочу сделать свой компилятор( ), мне может это понадобится... но оставим это на потом...
compiler
5.07.2007 0:28
двигаюсь дальше появляются новые ошибки... в этот раз
Цитата
Only static variables can be used in static methods or outside methods
в методе
function getXMax():integer; //public begin getXMax:=high (map.a); //public a: array[0..10, 0..10] of integer; end;
что делать?
volvo
5.07.2007 1:09
map это у тебя что? Не имя ли объекта? Если так, то нельзя обращаться к матрице в НЕклассовом методе через map.a, достаточно написать просто:
function getXMax(): integer; begin result := high(a); end;
compiler
8.07.2007 21:28
тут я разобрался, но у меня возникают проблемы при размещении обьекта в модуле берем программу volvo приабразовываем в модуль(прикрепленный файл) и аналогичном тесте получаю Error:
Потому, что у тебя программа не знает о переопределении в модуле оператора присваивания, ей надо об этом сообщить... Добавь в модуле перед Implementation описания:
А можна где нибудь посмотреть пример вызова метода другого обьекта(который описан в другом модуле) из метода другого обьекта(который также реализован в отдельном модуле)?
заранее благодарен.
Добавлено через 3 мин. у меня возникает Class isn’t a parent class of the current class
volvo
9.07.2007 0:27
Можно посмотреть пример, как ты это делаешь?
compiler
9.07.2007 0:38
Цитата(volvo @ 8.07.2007 20:27)
Можно посмотреть пример, как ты это делаешь?
{$mode objfpc} unit e1; interface type o1 = object procedure p(); end; implementation procedure o1.p(); begin end; end.
и
{$mode objfpc} unit e2; interface type o2 = object constructor create; procedure pr(); end; implementation uses e1; procedure o2.pr(); begin o1.p();end; end.
volvo
9.07.2007 1:19
Ты пытаешься вызвать процедуру через тип объекта, а для этого надо static метод... В FPC нереализуемо, если у тебя o1 является Object-ом, а не Class-ом... С Class-ом будет так:
{$mode objfpc}
unit e1; interface
type o1 = class class procedure p(); end;
implementation
procedure o1.p(); begin end;
end.
, тогда
procedure o2.pr(); begin o1.p(); // здесь - Ok end;
Ну, а на самом деле я думаю, что тебе надо бы объявить экземпляр объекта типа o1, и вызывать для него метод P:
var ex1: o1; procedure o2.pr(); begin ex1.p(); end;
compiler
9.07.2007 16:42
м-да...
Цитата(volvo @ 8.07.2007 21:19)
Ты пытаешься вызвать процедуру через тип объекта, а для этого надо static метод...
тоесть если я сделаю все static оно может заработает но не на FPC
Цитата(volvo @ 8.07.2007 21:19)
В FPC нереализуемо, если у тебя o1 является Object-ом, а не Class-ом...
ух єти классы.. где про них можна прочитать(руководство смотрел только больше запутался и вообще потерял способность различать обьекты и классы оф. сайт FP, моя тема...)
Цитата(volvo @ 8.07.2007 21:19)
Ну, а на самом деле я думаю, что тебе надо бы объявить экземпляр объекта типа o1, и вызывать для него метод P:
в том же и дело что это только модули подключаемые к программе...
ЗЫ попробую через классы... ЗЗЫ хотелось бы услышать твое обьяснение о различии обьектов и классов...
volvo
9.07.2007 16:50
Цитата
хотелось бы услышать твое обьяснение о различии обьектов и классов...
Того, что есть в документации (prog.pdf, chapters 8.2.12/8.2.13) недостаточно?
compiler
9.07.2007 17:03
Цитата(volvo @ 9.07.2007 12:50)
Того, что есть в документации (prog.pdf, chapters 8.2.12/8.2.13) недостаточно?
Class ... just like objects...
volvo
9.07.2007 17:28
Ну, отличий тоже хватает:
1) (там же - 8.2.13)
Цитата
Contrary to objects, all data fields of a class are always stored in heap memory.
Дальше - из ref.pdf: 2)
Цитата
6.3.2 Virtual methods Classes have virtual methods, just as objects do. There is however a difference between the two. For objects, it is sufficient to redeclare the same method in a descendent object with the keyword virtual to override it. For classes, the situation is different: virtual methods must be overridden with the override keyword. Failing to do so, will start a new batch of virtual methods, hiding the previous one.
3) Добавлены message methods для классов ... 4) Уровень доступа published
+ еще одно отличие: operators overloading прекрасно работает с Object-ами, но с Class-сами происходят очень непонятные вещи...
Цитата(compiler)
в том же и дело что это только модули подключаемые к программе...
Ну и что, что только модули? Если модуль, так можно бессмысленно писать что-то? Что ты думаешь будет делаться в этом фрагменте:
o1.p();
? Особенно, если ни один экземпляр класса (или объекта) еще не инстанцирован?
Это текстовая версия — только основной контент. Для просмотра полной версии этой страницы, пожалуйста, нажмите сюда.