Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2010.08.27;
Скачать: CL | DM;

Вниз

[ООП] Хочу странного   Найти похожие ветки 

 
oxffff ©   (2010-03-08 23:31) [40]


> Игорь Шевченко ©   (08.03.10 23:29) [38]
> oxffff ©   (08.03.10 23:20) [37]
>
>
> > Есть формальная теория рекомендую к ней обратиться.
>
>
> Есть синтаксис конкретных языков. Можно я буду к нему обращаться
> ? :)


Ради бога. Есть теория можно я буду к ней обращаться?


 
Игорь Шевченко ©   (2010-03-08 23:33) [41]

oxffff ©   (08.03.10 23:31) [40]


> Есть теория можно я буду к ней обращаться?


Ради бога. Только ты пиши, когда к теории обращаешься, чтобы было понятно, договорились ?


 
oxffff ©   (2010-03-08 23:36) [42]


> Игорь Шевченко ©   (08.03.10 23:33) [41]
> oxffff ©   (08.03.10 23:31) [40]
>
>
> > Есть теория можно я буду к ней обращаться?
>
>
> Ради бога. Только ты пиши, когда к теории обращаешься, чтобы
> было понятно, договорились ?


Договорились. И?


 
oxffff ©   (2010-03-08 23:40) [43]

Еще немного теории

Of course, if one hides a previously public method, m, in a subclass SC of
C, then SC no longer generates objects whose type is a subtype of the objects
generated by C. Objects generated from C can respond to message m, while
those generated from SC cannot.


 
Alkid ©   (2010-03-09 00:00) [44]


> oxffff ©   (08.03.10 23:16) [36]
> Вообще нужно говорить наверно о теории типов, а не о LSP.
>  
> Так вот, то что положено в С++ это решение автора со всеми
> вытекающими.

И с какими же вытекающими? Возможность порождать подкласс, не являющийся подтипом, не противоречит абсолютно ничему. Закрытое наследование, по сути, является разновидностью композиции.

В С++ это выдерживается строго, ты не можешь приводить класс к закрытому базовому классу без применения тяжелой артиллерии в виде reinterpret_cast или C-style cast.


Так же как и в JAVA знаменитая проблема с подтипами массивов.

Можно поподробнее? Я не знаток Java, так что не в курсе проблемы.


> Читайте теорию господа.

Теория - это хорошо, но она пока не объясняет, в чем же ты усмотрел "нетипобезопасность" и прочий криминал. Нетипобезопасность, по моему пониманию, это когда ты присваиваешь переменной значение нелегального типа. Ну, есть у тебя указатель на Foo, а ты тыкаешь его в экземпляр Bar. Тогда у тебя будут все радости, типа AV, порчи памяти и так далее.


 
Alkid ©   (2010-03-09 00:06) [45]


> oxffff ©   (08.03.10 21:16) [27]
> В Delphi есть делегирование реализации implements, если
> я правильно понял вопрос.
> В остальном я скоро приеду и у нас будет возможность посидеть
> и обсудить это. :)

Да, ты правильно понял вопрос.
А я, видимо, стал забывать Дельфи уже :)


 
oxffff ©   (2010-03-09 00:22) [46]


> Alkid ©   (09.03.10 00:00) [44]
>
> > oxffff ©   (08.03.10 23:16) [36]
> > Вообще нужно говорить наверно о теории типов, а не о LSP.
>
> >  
> > Так вот, то что положено в С++ это решение автора со всеми
>
> > вытекающими.
>
> И с какими же вытекающими? Возможность порождать подкласс,
>  не являющийся подтипом, не противоречит абсолютно ничему.
>  Закрытое наследование, по сути, является разновидностью
> композиции.
>
> В С++ это выдерживается строго, ты не можешь приводить класс
> к закрытому базовому классу без применения тяжелой артиллерии
> в виде reinterpret_cast или C-style cast.
>


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


>
> Так же как и в JAVA знаменитая проблема с подтипами массивов.
>
>
> Можно поподробнее? Я не знаток Java, так что не в курсе
> проблемы.
>
>


JAVA правило для массивов.
B[] является подтипом A[], если B является подтипом A.

Что приводит к тому, что в массив фруктов можно добавить овощи.


> > Читайте теорию господа.
>
> Теория - это хорошо, но она пока не объясняет, в чем же
> ты усмотрел "нетипобезопасность" и прочий криминал. Нетипобезопасность,
>  по моему пониманию, это когда ты присваиваешь переменной
> значение нелегального типа. Ну, есть у тебя указатель на
> Foo, а ты тыкаешь его в экземпляр Bar. Тогда у тебя будут
> все радости, типа AV, порчи памяти и так далее.


см. выше+
Every value generated in a program is associatedwith a type, either explicitly
or implicitly. In a strongly typed language, the language implementation
is required to provide a type checker that ensures that no type errors will occur
at run time.


 
Игорь Шевченко ©   (2010-03-09 00:25) [47]

oxffff ©   (09.03.10 00:22) [46]


> Every value generated in a program is associatedwith a type,
>  either explicitly
> or implicitly. In a strongly typed language, the language
> implementation
> is required to provide a type checker that ensures that
> no type errors will occur
> at run time.


Если тебя не затруднит, ты по-русски сразу пиши, а ?
Задолбало уже.


 
oxffff ©   (2010-03-09 00:32) [48]


> Игорь Шевченко ©   (09.03.10 00:25) [47]
> oxffff ©   (09.03.10 00:22) [46]
>
>
> > Every value generated in a program is associatedwith a
> type,
> >  either explicitly
> > or implicitly. In a strongly typed language, the language
>
> > implementation
> > is required to provide a type checker that ensures that
>
> > no type errors will occur
> > at run time.
>
>
> Если тебя не затруднит, ты по-русски сразу пиши, а ?
> Задолбало уже.


Все я спать пошел. :)


 
Германн ©   (2010-03-09 00:44) [49]


> Игорь Шевченко ©   (09.03.10 00:25) [47]

Вроде нет проблем с переводом. Всё с первого взгляда понятно.
Или я "не в теме"?


 
Alkid ©   (2010-03-09 09:53) [50]


> oxffff ©   (09.03.10 00:22) [46]
> Применение тяжелой артилерии(а значит и передача ответственности
> программисту) означает, что компилятор(среда) не может гарантировать
> безопасность программы самостоятельно, а это в свою очередь
> означает не 100% безопасность типов.

Безусловно. Собственно, эти типы приведения нужны *только* для низкоуровневой работы с памятью. За создание закрытого наследования и приведения его потом к приватной базе через reinterpret_cast надо расстреливать через повешение. При нормальном проектировании такого быть не должно, что не отменяет допустимость закрытого наследования.


> Every value generated in a program is associatedwith a type,
>  either explicitly
> or implicitly. In a strongly typed language, the language
> implementation
> is required to provide a type checker that ensures that
> no type errors will occur
> at run time.

Ну вот и поясни мне, как закрытое наследование порождает "error at run time", а то я пока не понимаю этого.


 
oxffff ©   (2010-03-09 10:11) [51]


> Ну вот и поясни мне, как закрытое наследование порождает
> "error at run time", а то я пока не понимаю этого.


Очень просто. Есть класс B, который наследует приватно от А, скрывая интерфейс А, и выставляя некий свой другой. Что означает, что изменение значений закрытой части в B, контролирует B, но не внешнее окружение. А это в свою очередь означает, что эти закрытые члены могут принимать некие определенные значения(их домен значений в B, например подмножество всех допустимых значений в А), а также все отношения между этимим полями должны быть определенными и могут иметь предназначение отличное от их предназначения в А. Поэтому если B трактовать как A(отношение подтипа), по мы нарушает абстракцию B, Что могут вызвать ошибки времени исполнения, в случае если значения вышли из домена значений допустимых в B(например индекс в неком расделенном массиве). Надеюсь я понятно объяснил. :)


 
oxffff ©   (2010-03-09 10:14) [52]


>  Поэтому если B трактовать как A(отношение подтипа), по
> мы нарушает абстракцию B, Что могут вызвать ошибки времени
> исполнения, в случае если значения вышли из домена значений
> допустимых в B(например индекс в неком расделенном массиве).
>  Надеюсь я понятно объяснил. :)


например для А допустимы индексы от 1 до 100.
Для B допустимы индексы от 5 до 87.
Значение индекса вне [5,87] будет некорректным в B, что приведет к ошибке в его работе и значит и ошибки Run-time. :)


 
Alkid ©   (2010-03-09 10:46) [53]


> oxffff ©   (09.03.10 10:11) [51]
> oxffff ©   (09.03.10 10:14) [52]

Не, я не понял, что ты имеешь в виду. Закрытое наследование не порождаем подтипа. Т.е.:

class A { };
class B : private A {};
...
A* a = new B(); // Ошибка компиляции!

Это означает, что ты не можешь передать B туда, где применим А, принцип подстановки не работает. Пользователь класса B не знает о том, что тот унаследован от A, это является исключительно деталью реализации.

В общем, жду примера, в котором без применения всяких дурных кастов ты получишь нетипобезопасную программу. Т.е. компилирующуюся, но падающую в run-time от ошибки типов.


 
jack128_   (2010-03-09 10:52) [54]


> Некто   (08.03.10 13:27)  

тут обсуждение в какие то непнятные теоретические дебри и особенности cpp, давайте ближе к телу вопроса.

мя в предложенной схеме смущают два момента:  
1) весь публичный интерфейс - полиморфный.
2) отсутствие protected (в виду отсутствия наследования классов)

в качестве примера шаблонный метод реализуем:

TBase = class
protected
 procedure DoStep1(); virtual;
 procedure DoStep2(); virtual;
 procedure DoStep3(); virtual;
public
 procedure DoWork(); // вызывает последовательно DoStep1/DoStep2/DoStep3
end;

TChild1 = class(TBase)
protected
 procedure DoStep1(); override;
 procedure DoStep2(); override;
 procedure DoStep3(); override;
end;

TChild2 = class(TBase)
protected
 procedure DoStep1(); override;
 procedure DoStep2(); override;
 procedure DoStep3(); override;
end;

по твоей схеме эту иерархию мона преобразовать так:

IBase = interface
 procedure DoStep1();
 procedure DoStep2();  
 procedure DoStep3();
end;

procedure DoWork(base: IBase);
begin
 base.DoStep1();
 base.DoStep2();  
 base.DoStep3();
end;

но тогда отдельные шаги передут в публичный интерфейс и станут доступны каждому встречному поперечному.

либо просто объявить
IWorker = interface
 procedure DoWork();
end

но тогда теряется шаблонность.  Как быть??


 
oxffff ©   (2010-03-09 10:55) [55]


> Alkid ©   (09.03.10 10:46) [53]
>
> > oxffff ©   (09.03.10 10:11) [51]
> > oxffff ©   (09.03.10 10:14) [52]
>
> Не, я не понял, что ты имеешь в виду. Закрытое наследование
> не порождаем подтипа. Т.е.:
>
> class A { };
> class B : private A {};
> ...
> A* a = new B(); // Ошибка компиляции!
>
> Это означает, что ты не можешь передать B туда, где применим
> А, принцип подстановки не работает. Пользователь класса
> B не знает о том, что тот унаследован от A, это является
> исключительно деталью реализации.
>
> В общем, жду примера, в котором без применения всяких дурных
> кастов ты получишь нетипобезопасную программу. Т.е. компилирующуюся,
>  но падающую в run-time от ошибки типов.


Ты определись что ты хочешь?

Я написал что применение закрытого наследования при сохранении отношений подтипа для подклассов или использования cast"ов является небезопасным.


 
Alkid ©   (2010-03-09 11:06) [56]


> oxffff ©   (09.03.10 10:55) [55]

А я писал, что подтип и подкласс - не синонимы, что допустимо порождать подкласс, не являющийся подтипом, и что за касты расстреливать надо на месте :)

Смотри [44], откуда все началось.


 
Alkid ©   (2010-03-09 11:09) [57]


> jack128_   (09.03.10 10:52) [54]


ISteps = interface
procedure DoStep1();
procedure DoStep2();  
procedure DoStep3();
end;

IWorker = interface
procedure DoWork();
end

TWorker = interface(IWokrer)
 FSteps : IWorker; // Либо инжектируется в конструктор, либо создается там же.
end;

procedure TWorker.DoWork(base: IBase);
begin
FSteps.DoStep1();
FSteps.DoStep2();  
FSteps.DoStep3();
end;


Шаблонность сохраняется.


 
Alkid ©   (2010-03-09 11:10) [58]

Тьфу, поправочка:

TWorker = interface(IWokrer)
FSteps : ISteps; // Либо инжектируется в конструктор, либо создается там же.
end;


 
jack128_   (2010-03-09 11:15) [59]


> Шаблонность сохраняется.

ну как же она сохраняется то, если мы мы работаем через интерфейс IWorker?


 
oxffff ©   (2010-03-09 11:16) [60]


> Alkid ©   (09.03.10 11:06) [56]
>
> > oxffff ©   (09.03.10 10:55) [55]
>
> А я писал, что подтип и подкласс - не синонимы, что допустимо
> порождать подкласс, не являющийся подтипом, и что за касты
> расстреливать надо на месте :)
>
> Смотри [44], откуда все началось.


Что смотреть?
Я еще раньше написал [28], что изменение видимости в сторону уменьшения пагубно влияет на отношении подтипов при сохранении отношения формально подклассов.
Началось все с [28]. Где речь шла о наделении языка такой возможностью, при сохранении остальной части.


 
Alkid ©   (2010-03-09 11:21) [61]


> jack128_   (09.03.10 11:15) [59]

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

Здесь имеем тоже самое, только реализация подменяется не путем наследования, а путем инжектирования другой реализации ISteps. Это, кстати, вполне себе обычный паттерн, который применяется и без залезания в те дебри, в которые я вознамерился тут залезть :)


 
Alkid ©   (2010-03-09 11:24) [62]


> oxffff ©   (09.03.10 11:16) [60]

Понятно, имеется некий мисандерстендинг :) Там ты отвечал на пост Игоря :)
Короче, я хочу странного, но не настолько, что бы сохранять отношение подтипа с закрытым наследованием :) Считаю, что этот вопрос исчерпан :)


 
jack128_   (2010-03-09 11:27) [63]


> Я думал, что ты под шаблоном понимаешь метод DoWork, который
> оперирует методами DoStepX(), реализация которых может быть
> подменена в наследниках. Так?

именно + то, что этот метод НЕвиртуален. ТО есть мы фиксируем реализацию этого метода, не даем никому её подменить. В твоем же коде - я всегда могу написать свой реализатор IWorker который будет делать все что хочешь, только не вызывать шаги.  
собственно я ж написал как эту проблему избежать, нужно просто вызов шагов загнать в обычную процедуру (см [54])


 
Alkid ©   (2010-03-09 11:30) [64]


> jack128_   (09.03.10 11:27) [63]

А, ты об этом. Ну да, можно и так сделать. Это не влияет на замену наследования делегирования.


 
jack128_   (2010-03-09 11:32) [65]

у мя в [54] еще второй пункт есть. по поводу того, что в исходном коде DoStepX() - доступны только подклассам - а в твоем варианте - они доступны кому угодно


 
Игорь Шевченко ©   (2010-03-09 12:25) [66]

Не удержусь:

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

Эрик Реймонд, "Искусство программирования для Unix"


 
Alkid ©   (2010-03-09 12:37) [67]


> Игорь Шевченко ©   (09.03.10 12:25) [66]

и-и-и? ;) Какая связь с обсуждаемым вопросом?


 
Игорь Шевченко ©   (2010-03-09 13:11) [68]

Alkid ©   (09.03.10 12:37) [67]

Скорее, с развитием и ответвлениями обсуждаемого вопроса.


 
Alkid ©   (2010-03-09 13:35) [69]


> Игорь Шевченко ©   (09.03.10 13:11) [68]

А, понятно. Просто то, что я предлагаю, на количество уровней абстракции не влияет. Те же яйца, вид сбоку, если в двух словах :)


 
oxffff ©   (2010-03-09 14:34) [70]


> Alkid ©   (09.03.10 11:24) [62]
>
> > oxffff ©   (09.03.10 11:16) [60]
>
> Понятно, имеется некий мисандерстендинг :) Там ты отвечал
> на пост Игоря :)
> Короче, я хочу странного, но не настолько, что бы сохранять
> отношение подтипа с закрытым наследованием :) Считаю, что
> этот вопрос исчерпан :)


Отношение подтипа с закрытым наследованием можно сохранить, если выдать свой собственный интерфейс идентичный необходимому типу(например супертипу)(однако возникнет проблема бинарной совместимости, поскольку смещения поменяются. Но если изменить способ обращения(исполнения кода, например интерпретатор) без привязки к смещению, то это можно решить. Более того есть такие реализации без "вертикальной сабтипизациии".


 
Piter ©   (2010-03-09 14:54) [71]

Игорь Шевченко ©   (09.03.10 12:25) [66]
Эрик Реймонд, "Искусство программирования для Unix"


Игорь, я так понимаю вы в настоящее время интересуетесь программингом в сторону *nix платформ.

Если не сложно - посоветуйте что прочитали, что думаете, какие книжки особо понравились, какой нужен уровень для их корректного прочтения?

Еще вопрос - какие языки, среды, технологии используете для программинга под *nix? Вас интересует именно *nix как таковой или в сфере кросс-платформенных приложений? На чем остановились?

P.S. Эрик C. Реймонд - Искусство программирования для Unix, это я так понимаю как раз ликбез-обзор по существующим технологиям?


 
Alkid ©   (2010-03-09 15:02) [72]


> oxffff ©   (09.03.10 14:34) [70]

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


 
oxffff ©   (2010-03-09 15:22) [73]


> Alkid ©   (09.03.10 15:02) [72]
>
> > oxffff ©   (09.03.10 14:34) [70]
>
> Интерфейсы спасут отца русской демократии от бинарной совместимости.
>  С другой стороны, зачем сохранять отношения подтипа, если
> закрытое наследование для того и сделано, что бы это отношение
> ликвидировать? :)


От бинарной несовместимости? :)
Вот вот и я думаю, что в твоем вопросе [0] интерфейсы спасут тебя. :)
А Delphi impelements наделит тебя необходимой силой воина со сложностью. :)

Закрытое наследование является формой агрегации реализации. Отношение подтипа можно сохранить например для того, чтобы внести в реализацию некие изменения, полностью заменив или частично. Однако получается, что привычная VMT уже не нужна. А приобретает некую форму разрешения как для мультиметода в run time.


 
GDI+   (2010-03-09 19:33) [74]


> Некто   (08.03.10 13:27)
>
> При спорах вида "С++ vs X", где Х - любой объектно-ориентированный
> ЯП, поддерживающий единичное наследование, неизбежно возникает
> ответвление спора на тему "множественное наследование vs.
>  единичное наследование". Защитники МН упирают на бОльшую
> гибкость и возможности, которые дает МН, противники - на
> то, что МН усложняет реализацию языка, сам язык и что МН
> вообще не нужно.


Множественное наследование необходимо. Без него никак. Но в нормальных языках множественное наследование реализовано через интерфейсы.

А множественное наследование реализации, а не декларации это изврат и нигде не используется.


 
GDI+   (2010-03-09 19:34) [75]


> Игорь Шевченко ©   (08.03.10 13:51) [7]
>
> Есть множественное наследование интерфейса и множественное
> наследование реализации.
Хорошо и то, и другое.


Плохо. Хотя, если цель обфускация кода, то хорошо.


 
Игорь Шевченко ©   (2010-03-09 19:42) [76]

GDI+   (09.03.10 19:33) [74]


> А множественное наследование реализации, а не декларации
> это изврат и нигде не используется.


Кругозор надо расширять, не будешь ерундой болтать


 
Alkid ©   (2010-03-09 19:50) [77]


> GDI+   (09.03.10 19:33) [74]
> Множественное наследование необходимо. Без него никак. Но
> в нормальных языках множественное наследование реализовано
> через интерфейсы.
>
> А множественное наследование реализации, а не декларации
> это изврат и нигде не используется.

Аргументируй.
Кстати, насчет "нигде не используется" ты не прав. В stl очень даже используется в виде trait-классов. На прошлой работе применял множественное наследования для реализации mixin-style.

Так что хочу услышать аргументированное изложение недостатков множественного наследования.


 
GrayFace ©   (2010-03-11 02:41) [78]

oxffff ©   (08.03.10 21:34) [28]
Этой возможности быть и не должно. :)
Поскольку, если B является подклассом A, то B является подтипом A.
Если позволить менять видимость, то тогда B не будет являться подтипом A.
Поскольку B не может выступить в качестве А
(нарушение типобезопасности, то есть язык будет являться небезопасным)

Лучше было бы, если бы была. Это очень полезно для published свойств, иногда полезно для public. При приведении к A эти методы можно будет вызвать. Т.е. прятанье должно быть чисто внешнее.
А то, как сейчас, плодить TCustom*, вписывать в published свойства под все версии Delphi - это не дело.

Спасибо за implements!


 
oxffff ©   (2010-03-11 08:40) [79]


> Лучше было бы, если бы была. Это очень полезно для published
> свойств, иногда полезно для public. При приведении к A эти
> методы можно будет вызвать. Т.е. прятанье должно быть чисто
> внешнее.
> А то, как сейчас, плодить TCustom*, вписывать в published
> свойства под все версии Delphi - это не дело.


Это всего лишь реализация VCL. К формальной теории отношения не имеет.


 
GrayFace ©   (2010-03-12 15:10) [80]

oxffff ©   (11.03.10 8:40) [79]
Это всего лишь реализация VCL. К формальной теории отношения не имеет.


При чем тут реализация VCL? Это свойство языка, которое было бы полезным.
Речь была о
Классические пуристы возражают против наследников, например, от TList. Их аргументы таковы, что наследнику в большинстве случаев не нужны методы предка Exchange, Move, и т.д.

Нету в Delphi возможность понизить область видимости - ну такой язык.


С этим данное "частичное" понижение видимости отлично бы справилось.



Страницы: 1 2 3 вся ветка

Текущий архив: 2010.08.27;
Скачать: CL | DM;

Наверх




Память: 0.68 MB
Время: 0.049 c
15-1268649323
Из батника
2010-03-15 13:35
2010.08.27
Удаление каталога


2-1266395128
urgun
2010-02-17 11:25
2010.08.27
TThread+TMemoryStream = исключения при чтении в буффер


15-1274387389
Юрий
2010-05-21 00:29
2010.08.27
С днем рождения ! 21 мая 2010 пятница


2-1271310301
vegarulez
2010-04-15 09:45
2010.08.27
Вопрос про XML


3-1239773025
Spot
2009-04-15 09:23
2010.08.27
Interbase через BDE