Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>> Тогда все дизайны в Delphi и Net ошибочны.
VD>Кое какие да. Обобщать бы я не стал.
S>> Возьмем для примера Stream.
VD>Ага возьми. Открой его дизасемблером и убедись, что он является базовой реализацией. В нем добрая половина методов имеет реализацию.
А зачем дизасемблером в роторе есть исходники и реализуют он только ассинхронные вызовы. VD>С другой стороны то, что нет IStream — это явный промох дизайна. Что поделаешь? Драли с ранних версий Явы.
Если объект создан от Stream то передавай его целиком. Если же нужна другая функциональность то просто внедряется класс наследник от Stream и делается импликит на него. VD>Наличие IStream позволило бы другим делать реализации стрима координально отличные от Stream. Например, можно было бы Сделать обертку над КОМ-овским IStream-ом.
Ком это прошлый век и не стоит на него оборачиваться, а для совместимости с ним в Delphi например есть классы хэлперы TStreamAdapter и TOleStream. S>> А уж других кастомных классов огромное множество, где в базовом классе практически реализована базовая функциональность, но расчитана на перекрытие,
VD>Вот прочти эти строки еще раз... В них суть. Интерфейс — это чистая абстракция. В то время как абстрактный класс — это базовая реализация.
Еще раз повторю интерфейсы нужны только для расширения функциональности где простого наследования не хватает. Представь если бы все наследники от Component были реализованы чере IComponent. S>> Интерфейсы нужны тогда, когда нужна дополнительная функциональность невозможная при наследовании от базового класса (некий аналог множественного наследования но реализованный на VMT), и работа с интерфейсами это несколько другой подход нежели наследование.
VD>Советую почитать какую-нибудь классику по ОО-дизайну и проектированию.
Большое спасибо за совет. Тот же Рихтер говорит, что абстрактные классы предпочтительней там где есть явное наследование и предпочтитель интерфейсы где это невозможно.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, LaFlour, Вы писали:
LF>Насколько правила женериков для С++ отличаются/подходят к #-вым? LF>Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
Насколько я понимаю шаблоны С++ это по сути шаблон, где многие операции приводятся за счет перегрузки методов и операций, что бы на этапе компиляции правильно собрать объект и уже затем откомпилировать. В Net дженерики это готовые к употреблению объекты т.к. подчиняются всем требованиям ООП и нельзя применять к типу операции не оговоренных на этапе создания. На самом деле шаблоны С++ выхолащивают ООП практически сводя программирование к конструированию примитивных объектов.
В дженериках все премущества и недостатки ООП — виртуальные методы, наследование и отслеживание типа на этапе разработки и завершение кода.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
VD>>Про ООП — это чущь.
S>А это почему??? Все ООП прекрасно вписывается. Если посмотришь мои Б++ деревья то там полное ООП на дженериках.
Вписывается это одно. А имеет отношение — это другое. Дженирик программинг — это отдельная и ни в коей мере не конкурирующая с ООП парадигма программирования.
Шаблоны в С++ прекрасно интегрируются с ООП.
... << RSDN@Home 1.1.0 stable >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
VD>>Как миниум тот кому будет нужно сможет сделать чистую реализацию так как он считает нужным.
S> Может я уже плох совсем но зачем internal классам интерфейсы и интрнальные интерфейсы????
А кто говорил про internal интерфейсы? Суть в том что ты предоставляешь свой класс, реализующий вобщем то обобщенную функциональность без какой либо возможности заменить его на свою реализацию, что есть кривой дизайн. Базовый класс вполне может быть internal, но вот интерфейс обязательно должен быть паблик.
S> А вот кому нужно сделать чистую реализацию ( в чем в данном случае я сильно сомневаюсь, что кому то это понадобиться)
Ты в принципе не можешь этого знать и надеяться на подобное по меньшей мере самонадеянно.
S>пусть поступает как я — все переписываю под себя,
Здравствуйте, VladD2, Вы писали:
VD>Пока что компилятор не дает их использовать вообще. По крайней мере не ясно как это сделать. Но намеки есть. По крайней мере компилятор осмысленно ругается на синтаксис описанный на PDC-шных слайдах.
Попробуй /d1clrnewSyntax. Может поменьше ругаться будет.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, LaFlour, Вы писали:
LF>>Насколько правила женериков для С++ отличаются/подходят к #-вым? LF>>Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
VD>В МС++ будут поддерживаться как старые добрые шаблоны, так и дженирики полностью совместимые с дотнетом (и Шарпом в частности).
А так-же будет поддерживаться смесь templates & generics. Например:
template < template < typename > class T >
class TTC {...};
generic < typename T >
ref class GenC {...};
TTC< GenC > var;
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, alexkro, Вы писали:
A>>Попробуй /d1clrnewSyntax. Может поменьше ругаться будет.
VD> Шайтан! Как узнал?
VD> PS
VD> Вот только стало ясно, что из обещанных вкусностей по сути есть только ^. А что с нее толку?
Это-же только альфа. Жди бету, там почти все будет. А пока можно спек почитать.
Здравствуйте, mrhru, Вы писали:
M>Ведь дженерик работая с переданным типом, обращается к вполне определённому подмножеству его методов/свойств. Назовём это подмножество интерфейсом, и скажем, что переданный тип реализует этот интефейс. А теперь передадим в бывший дженерик, а теперь обычный класс, это интерфейс — и получим то же самое. Не так ли? Ну да, теперь надо этот интерфейс ещё и описать. Но вряд ли это принципиальное отличие. M>Тогда что же?
M>PS. Естественно, не имею ввиду простые типы. Использование шаблонов на них — действительно удобно.
Прежде всего это отсутствие приведения типа,т.к. C# нет reinterCast или как его там короче без проверки. А проверка томозит.
Кроме всего прочего работа с объектами в Net дорогое удовольствие и где это возможно нужно работать с Value типмаи http://www.rsdn.ru/Forum/Message.aspx?mid=415352&only=1
Здравствуйте, mrhru, Вы писали:
M>Можно узнать, в чём же их принципиальное различие?
В подходах и списке решамых задач. С помощью полиморфизма нельзя достичь типобезопастности. Все проверки будет в рантайме.
M>Ведь дженерик работая с переданным типом, обращается к вполне определённому подмножеству его методов/свойств. Назовём это подмножество интерфейсом, и скажем, что переданный тип реализует этот интефейс. А теперь передадим в бывший дженерик, а теперь обычный класс, это интерфейс — и получим то же самое. Не так ли? Ну да, теперь надо этот интерфейс ещё и описать. Но вряд ли это принципиальное отличие. M>Тогда что же?
1. Дженирики ни как не завязаны ОО-концепции позволяя создавать чистые алогоритмы.
2. Дженирики позволяют оперировать с рипами разных размеров.
3. Дженерики обеспечивают дипобезопастность на этапе компиляции.
4. Дженирики позволяют создавать специализации интерфейсов, и т.п. извраты позоляющие существнно ускорить работу конечного приложения.
M>PS. Естественно, не имею ввиду простые типы. Использование шаблонов на них — действительно удобно.
Структуры простые типы?
Короче, полиморфизм и обобщенное программирование позволяют решать одни и те же задачи. Но по разному. И с совершенно разной эффектиностью.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, LaFlour, Вы писали:
LF>НУ я к тому что зная шаблоныы С++ лехгко ли будет применить данные знания при переходе на женерик шарповый, или всеже прийдется кардинально переучиваться
Лично мне даже не пришлось заглядывать в документацию. Дженерики в Шарпе очень похожи на С++, но проще и применимы кроме всего прочего еще и к делегатам и интерфейсам.
... << RSDN@Home 1.1.0 stable >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
LF>Насколько правила женериков для С++ отличаются/подходят к #-вым? LF>Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
Насколько я знаю в С++ не джинериков. Есть шаблоны но это абсолютно другое. Одно просто огромное и главное отличие — это то, что шаблоны в С++ — сущьность времени компиляции. В .NET же джинерики — сущьность рантайм. Т.е ты можешь написать скажем свою супер пупер коллекцию обьектов и сделать её параметризуемой, причём в скомпилированной сборке будет находится именно джинерик. Т.е параметризуеммый класс. Ессно данную фичу мы имеем исключитьльно из за того, что реально в сборке лежит MSIL, и CLR уже в рантайме компилирует твой класс для данного типа. Причём для всех reference типов это делается единажды, а для value каждый раз для нового типа.
Здравствуйте, orangy, Вы писали:
O>Здравствуйте, Serginio1, Вы писали:
S>> А плюс шаблонов [C++] только в скорости зс счет вызовов прямых (Inline) методов и прямого сравнения за счет перегрузки операторов. Выигрыш в итоге не принципиальный особенно в идеалогии Net. O>Ну я не стал бы так вот заявлять, у шаблонов множество разнообразных применений, включая лямбда-исчисление. См. boost, например. O>К тому же настолько категоричные заявления смотрятся, мягко говоря, странно после твои слов: O>
O>Могу ошибаться т.к. не программирую на С++.
Я как собака понимаю С++ но не пишу, не только из принципиальных соображений но из-за его по моему мнению анахронизма. На 1С пишу только ради денег.
Я не говорю, что шаблоны не нужны. Весь С++ на нем построен и это его главное премущество вышедшее и Ассемблера. Но времена меняются и чистое ООП вытесняет такие подходы. Интересно посмотреть что будет с С++ через 3 года.
Главное принцип построения результирующего кода. В итоге происходит сначала формирование исходного кода на С++ а затем уже в машинный код. Получить машинный код можно и другими путями.
Готов выслушать аргументированное категоричное мнение отличное от моего.
и солнце б утром не вставало, когда бы не было меня
S> Дело в том что BTCustomLevel содержит общие поля для наследников и поэтому такой подход единственный.
Так не нужно пихать данные в абстракции.
S>А зачем городить интефейс если через наследование получаешь более оптимальную структуру класса ??? ООП однако.
И ты еще рассуждаешь об ООП. Интерфейс — это чистая абстракция. Абстрактные класы нужно исключительно для создания частично реализованных классов. Если вдруг появлются такие извраты как у тебя — это верный признак неверного дизайна.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> Влад в Моем случае только 2 уровня самый нижний и верхние. Зачем мне там интерфейсы????
Ты делаешь реализацию общего алгорима/струкутры данных. Сделать человеческий интерфейс в данном случае просто необходимо.
Такие вщи тяжело обяснять. Нужно прочуствовать к чему ведет обратный подход.
S> Кроме всего прочего кастомный предок имеет общие поля которые легче описать в базовом классе.
Содай интерфейс и унаследуй от него абстрактый класс реализующий нужные методы.
Как миниум тот кому будет нужно сможет сделать чистую реализацию так как он считает нужным.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD> Будем надяеться, что к выходу релиза дотнета 1.2 он будет соотвествовать спецификации на тот же Шарп 2.0 и при вызовах методов интерфейсов у вэлью-типов не будет произход боксинга (как сейчас).
А как это вообще можно реализовать?
1. Физически в структуре нет метаданных, только поля. Как её без "обёртывания" можно в интерфейс превратить?
2. Кто будет боксить при вызове ToString на интерфейсе, полученном от структуры?
VD> На стороне шаблонов: VD>1. Гибкость. VD>2. Производительность.
VD>На стороне дженириков: VD>1. Поддрежка технологии Интели-сенс. VD>2. Распростронение в виде промежуточного кода, а стло быть, возможность использования без наличия исходного кода.
Кроме того, возможности генериков существенно ограничены синтаксисом. Слава богу, хоть в C# гениальные провидцы (вроде Александреску) не будут делать из наших мозгов котлету.
Здравствуйте, VladD2, Вы писали:
VD>А я и не перегибаю. Чем бы помешал интерфейс в данном случае?
Отсутствие гарантии правильной реализации асинхронных операций. Т.е. сам интерфейс конечно не помешал бы, но при использовании в своих классах я бы наружу выставлял запрос именно Stream а не IStream, поскольку это надежнее, а в плане гибкости ничего на практике не меняется. Хотя совсем правильным было бы вынесение того что реализовано в Stream в отдельный класс-обертку, а интерфейс чтобы описывал только то, что относится непосредственно к самому потоку.
VD>Я эту обертку могу сделать из без Stream. Вопрос в том, что если мне по каким-то причинам неподойдет реализация от МС,
Давай конкретно — по каким причинам тебе может не подойти конкретно Stream.
AVK>>Нет там никакой реализации, касающейся непосредственно самого стрима. Ты бы вместо того чтобы спорить посмотрел что в Stream реализовано. А то эдак можно докатиться до требования реализации собственного формата VMT.
VD>Факт в том, что там уже что-то реализовано. И нет никакой гарантии, что это что-то не окажется лишним/вредным.
Точно так же факт что много чего реализовано в CLR, JIT и "нет никакой гарантии, что это что-то не окажется лишним/вредным". Делать абстрактным все и вся это другая крайность, которая тоже ни к чему хорошему не приведет. Нужно выбирать золотую середину — где то базовые классы, где то интерфейсы.
Здравствуйте, Serginio1, Вы писали:
S> В том то и дело, что не писал я интерфесы колекций. Это не всегда и нужно,
Для коллекций это нужно всегда.
S> как DBTable,
У DataTable есть интерфейс, IListSource. Кроме того DataTable это всего лишь часть коллекции. Другая часть, DataView , реализует IList, IBindingList, ITypedList.
S> но если нужно то прикрутить на public методах недолго.
Тебе недолго. А тому кто будет этим пользоваться просто невозможно. Кроме того просто прикрутить интерфейс недостаточно, необходимо еще и сменить на интерфейс все внешние ссылки.
Насколько правила женериков для С++ отличаются/подходят к #-вым?
Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
Здравствуйте, LaFlour, Вы писали:
LF>Насколько правила женериков для С++ отличаются/подходят к #-вым? LF>Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
Здравствуйте, LaFlour, Вы писали:
LF>Насколько правила женериков для С++ отличаются/подходят к #-вым? LF>Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
В МС++ будут поддерживаться как старые добрые шаблоны, так и дженирики полностью совместимые с дотнетом (и Шарпом в частности).
... << RSDN@Home 1.1.0 stable >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
НУ я к тому что зная шаблоныы С++ лехгко ли будет применить данные знания при переходе на женерик шарповый, или всеже прийдется кардинально переучиваться
"VladD2" <forum@rsdn.ru> wrote in message news:447454@news.rsdn.ru...
From: VladD2 rsdn www.optim.ru/cs
Здравствуйте, LaFlour, Вы писали:
LF>Насколько правила женериков для С++ отличаются/подходят к #-вым? LF>Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
В МС++ будут поддерживаться как старые добрые шаблоны, так и дженирики полностью совместимые с дотнетом (и Шарпом в частности).
... << RSDN@Home 1.1.0 stable >>
Re: Generic в C# и C++? Оценить
Здравствуйте, LaFlour, Вы писали:
LF>НУ я к тому что зная шаблоныы С++ лехгко ли будет применить данные знания при переходе на женерик шарповый, или всеже прийдется кардинально переучиваться
Еще раз дженерики в Net это полноценные классы и описатели. Ты задаешь только тип и интерфесы поддерживаемые им.
например
internal abstract class BTCustomLevel<K,V>
{
public int Level;
public BTIndexPP<K,V> Header;
public int index;
public BTParentLevel<K,V> Parent;
public BTCustomLevel<K,V> Child;
public abstract void First();
..................................
internal sealed class BTNullLevel<K,V>: BTCustomLevel<K,V>
{
public BTNullLevel(BTIndexPP<K,V> Header)
{
Level = 0;
this.Header = Header;
page = new NullPage<K,V>();
}
public override void First()
{ index = -1; }
.................................................
internal sealed class BTParentLevel<K,V>: BTCustomLevel<K,V>
{
public ParentPage<K> page;
public override void First()
{
index = 0;
Child.SetPage(this.page.PageItems[0].ChildPage);
Child.First();
}
.............................................
public class BTIndexPP<K,V>
{
internal IKeyComparer<K> Comp;
internal BTCustomLevel<K,V> Ind;
internal BTNullLevel<K,V> NullLevel;
internal int RecordCount;
internal NullItem<K,V> NullItemAsNull;
И работаешь как с обычными объектами. Если например в Delphi тоже можно применять такой подход, но приходится копировать объект и присваивать свой тип, что неудобно то сдесь уже все подставляется автоматически по шаблону.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
VD>>>Про ООП — это чущь.
S>>А это почему??? Все ООП прекрасно вписывается. Если посмотришь мои Б++ деревья то там полное ООП на дженериках.
VD>Вписывается это одно. А имеет отношение — это другое. Дженирик программинг — это отдельная и ни в коей мере не конкурирующая с ООП парадигма программирования.
Я бы сказал расширяющаяя обычное понятие ООП. Т.К. неопределенные типы имеют право на жизнь за счет дополнительных параметров определяющие правило функционирования этих типов. Это намного лучше чем использовать нетипизированные указатели зная размер типа и приводя его к типизированной ссылке.
VD>Шаблоны в С++ прекрасно интегрируются с ООП.
Только интеграция эта происходит на этапе компиляции по сути являющиеся аналогом Copy-Paste-Replace только производимая компилятором. Это лично мое мнение. Но пообщавшись с Дженериками мне такой подход больше нравится и он единственный в объектном подходе в Net.
А плюс шаблонов только в скорости зс счет вызовов прямых (Inline) методов и прямого сравнения за счет перегрузки операторов. Выигрыш в итоге не принципиальный особенно в идеалогии Net.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> А плюс шаблонов [C++] только в скорости зс счет вызовов прямых (Inline) методов и прямого сравнения за счет перегрузки операторов. Выигрыш в итоге не принципиальный особенно в идеалогии Net.
Ну я не стал бы так вот заявлять, у шаблонов множество разнообразных применений, включая лямбда-исчисление. См. boost, например.
К тому же настолько категоричные заявления смотрятся, мягко говоря, странно после твои слов:
Здравствуйте, Serginio1, Вы писали:
S> Я бы сказал расширяющаяя обычное понятие ООП. Т.К. неопределенные типы имеют право на жизнь за счет дополнительных параметров определяющие правило функционирования этих типов. Это намного лучше чем использовать нетипизированные указатели зная размер типа и приводя его к типизированной ссылке.
Ничего они не расширяют. Это просто способ создания обобщенных алгоритмов. Не больше и не меньше.
S> Только интеграция эта происходит на этапе компиляции
Да. И учитывая возможности шаблонов это в некоторой степени оправданно. К тому же такова уж концепция С++. В нем почти все происходит в компайл-тайме.
S>по сути являющиеся аналогом Copy-Paste-Replace только производимая компилятором.
Гы. Если копи-пэст делает компилятор, то это уже называется повторное использование кода. Собственно джит делает почти тоже самое (особенно если учесть, что линкер в С++ выкидывает дублирующийся код).
S>Но пообщавшись с Дженериками мне такой подход больше нравится и он единственный в объектном подходе в Net.
Дело в том, что ты не достаточно "общался" с шаблонами. Они во многом гибче и производительнее. По сути дженирики решают две задачи: 1) повышают контроль типов в обобщенных алгоритмах, 2) повышают скорость кода. Так вот, тоже самое делают и шаблоны. Но они порождают потенциально более бытрый код, и ко всему прочему, позволют делать некоторые выкрутасы недоступные дженирикам. В свою очередь дженирики обладают свойствами компонентности и предоставлют такие фичи как дженерик-виртальные фукнкции, дженерик-делегаты и дженерик-интерфейсы. Этого уже нет в С++.
Таким образом дженирики — это просто другая реализация тогоже подхода. Со своими плюсами и со своими минусами. Однако тот факт, что с помпщью шаблонов можно создавать более оптимизированный код, говорит о том, что пункт 2) (своего предназначения) шаблоны выполняют лучше дженириков. Будем надеяться, что в будущем это исправится (возможно уже в релизе).
S> А плюс шаблонов только в скорости зс счет вызовов прямых (Inline) методов и прямого сравнения за счет перегрузки операторов. Выигрыш в итоге не принципиальный особенно в идеалогии Net.
Пол смысла в дженикиках — это скорость. Как ты мог заметить, в некоторых случаях, дженирики работают в десятки раз быстрее чем аналогичные полиморфные алгоритмы. Вторая заслуга — это строгая типизация. Так она в обоих случаях на всоте. Разве что можно записать в плюс дженирикам то, что они обеспечивают копилт-ворд при редактировании.
... << RSDN@Home 1.1.0 stable >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S>Но времена меняются и чистое ООП вытесняет такие подходы. Интересно посмотреть что будет с С++ через 3 года.
Кто чего вытесняет? Как только в С++ появились шаблоны все больше и больше кода пишется с их использованием. Так что верным скорее будет обратное утверждение: Времена меняется, и чистый ООП вытесняется "такими" подходами.
S> Главное принцип построения результирующего кода. В итоге происходит сначала формирование исходного кода на С++ а затем уже в машинный код. Получить машинный код можно и другими путями.
А что на Дельфи или Шарпе можно пропустить этап "формирования исходнго кода"?
S> Готов выслушать аргументированное категоричное мнение отличное от моего.
Для этого нужно сначало как следует аргументировать собственное мнение.
... << RSDN@Home 1.1.0 stable >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, der Igel, Вы писали:
DI>Hello, LaFlour!
DI>Ничего личного, но настойчиво рекомендую настроить ньюс-клиент в соттветсвии с DI>http://rsdn.ru/article/files/progs/rsdnnntp/rsdnnntp.xml и оформлять ответы в принятом на сайте стиле — сначала вопрос, потом ответ.
А никто не подскажет, как Оутлук (не экспресс) заставить квотить сообщения в таком же стиле?
... << RSDN@Home 1.1.0 stable >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Igor Trofimov, Вы писали:
S>> Я как собака понимаю С++ но не пишу
iT>Я тоже так думал, пока Александреску не почитал
отсюда вывод — читать такие книги вредно для самооценки и читать их не нужно.
как там в песне поется "I believe that beauty magazines promote low self-esteem".
"VladD2" <forum@rsdn.ru> wrote in message news:447891@news.rsdn.ru... > Здравствуйте, LaFlour, Вы писали: > > LF>НУ я к тому что зная шаблоныы С++ лехгко ли будет применить данные знания при переходе на женерик шарповый, или всеже прийдется кардинально переучиваться > > Лично мне даже не пришлось заглядывать в документацию. Дженерики в Шарпе очень похожи на С++, но проще и применимы кроме всего прочего еще и к делегатам и интерфейсам.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>>Но времена меняются и чистое ООП вытесняет такие подходы. Интересно посмотреть что будет с С++ через 3 года.
VD>Кто чего вытесняет? Как только в С++ появились шаблоны все больше и больше кода пишется с их использованием. Так что верным скорее будет обратное утверждение: Времена меняется, и чистый ООП вытесняется "такими" подходами.
S>> Главное принцип построения результирующего кода. В итоге происходит сначала формирование исходного кода на С++ а затем уже в машинный код. Получить машинный код можно и другими путями.
VD>А что на Дельфи или Шарпе можно пропустить этап "формирования исходнго кода"?
Можно применять уже скомпилированные пакеты или ассемБЛИ и на их основе делать новые классы.
S>> Готов выслушать аргументированное категоричное мнение отличное от моего.
VD>Для этого нужно сначало как следует аргументировать собственное мнение.
Аргументирую.
1. Этап Win32 завершен;
2. В Net шаблонов не будет или будет генерация новых классов из шаблонов может даже отдельной утилитой.
3. Дженерики намного удобнее шаблонов,т.к. ты пишешь в уже актуальном коде и есть ли смысл использовать громоздкие шаблоны при этом необходимо всегда иметь исходный код.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>> Я бы сказал расширяющаяя обычное понятие ООП. Т.К. неопределенные типы имеют право на жизнь за счет дополнительных параметров определяющие правило функционирования этих типов. Это намного лучше чем использовать нетипизированные указатели зная размер типа и приводя его к типизированной ссылке.
VD>Ничего они не расширяют. Это просто способ создания обобщенных алгоритмов. Не больше и не меньше.
S>> Только интеграция эта происходит на этапе компиляции
VD>Да. И учитывая возможности шаблонов это в некоторой степени оправданно. К тому же такова уж концепция С++. В нем почти все происходит в компайл-тайме.
S>>по сути являющиеся аналогом Copy-Paste-Replace только производимая компилятором.
VD>Гы. Если копи-пэст делает компилятор, то это уже называется повторное использование кода. Собственно джит делает почти тоже самое (особенно если учесть, что линкер в С++ выкидывает дублирующийся код).
S>>Но пообщавшись с Дженериками мне такой подход больше нравится и он единственный в объектном подходе в Net.
VD>Дело в том, что ты не достаточно "общался" с шаблонами. Они во многом гибче и производительнее. По сути дженирики решают две задачи: 1) повышают контроль типов в обобщенных алгоритмах, 2) повышают скорость кода. Так вот, тоже самое делают и шаблоны. Но они порождают потенциально более бытрый код, и ко всему прочему, позволют делать некоторые выкрутасы недоступные дженирикам. В свою очередь дженирики обладают свойствами компонентности и предоставлют такие фичи как дженерик-виртальные фукнкции, дженерик-делегаты и дженерик-интерфейсы. Этого уже нет в С++.
VD>Таким образом дженирики — это просто другая реализация тогоже подхода. Со своими плюсами и со своими минусами. Однако тот факт, что с помпщью шаблонов можно создавать более оптимизированный код, говорит о том, что пункт 2) (своего предназначения) шаблоны выполняют лучше дженириков. Будем надеяться, что в будущем это исправится (возможно уже в релизе).
S>> А плюс шаблонов только в скорости зс счет вызовов прямых (Inline) методов и прямого сравнения за счет перегрузки операторов. Выигрыш в итоге не принципиальный особенно в идеалогии Net.
VD>Пол смысла в дженикиках — это скорость. Как ты мог заметить, в некоторых случаях, дженирики работают в десятки раз быстрее чем аналогичные полиморфные алгоритмы. Вторая заслуга — это строгая типизация. Так она в обоих случаях на всоте. Разве что можно записать в плюс дженирикам то, что они обеспечивают копилт-ворд при редактировании.
Постараюсь объяснить мое понимание дженериков. Т.К. в Delphi нет шаблонов но нужно делать универсальные классы на неопределенных типах то я вводил переменные ссылки в которые затем передавались адреса реальных переменных с уже определенным типом в наследниках. Все операции с данным типом в базовом классе основывались только на размере и переменных — методов с передачей ссылок.
Но базовый класс определял весь код класса, а все дополнительные операции с типом определялись в наследниках с добавлением незначительного количества кода. При этом скорость падает всего в 2 раза по сравнению с интегерами а с другими типами разница небольшая, а с применением более оптимальных алгоритмов вообще были быстрее со стандартными классами.
Но это ООП в отличии от шаблонов где генерится новый класс для каждого типа.
Дженерики по своей сути это то что я делал раньше только с абстрактной типизацией на этапе конструирования класса.
Понимаю, что вызвал негодование огромного количества посетителей данного форума но это мое видение и моя позиция.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>>
S>>internal abstract class BTCustomLevel<K,V>
S>>
VD>Кстати, вместо abstract лучше использовать интерфейс:
VD>
VD>internal interface BTCustomLevel<K,V>
VD>
Дело в том что BTCustomLevel содержит общие поля для наследников и поэтому такой подход единственный.
А зачем городить интефейс если через наследование получаешь более оптимальную структуру класса ??? ООП однако.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
D>>А что на Дельфи или Шарпе можно пропустить этап "формирования исходнго кода"?
S> Можно применять уже скомпилированные пакеты или ассемБЛИ и на их основе делать новые классы.
Ну, это и в С++ можно. Есть же lib-ы, да и МС++ существует.
S> Аргументирую. S>1. Этап Win32 завершен;
Еще лет эдак 5-10 может протянуть. 5 так точно.
Ну, и к Шаблонам это отношение не имеет.
S>2. В Net шаблонов не будет или будет генерация новых классов из шаблонов может даже отдельной утилитой.
Открой МС++ и убидись, что в нем шаблоны использовать можно. В новых расширениях к МС++ идет речь о том, что разрешат наследовать менеджед-классы от шаблонов.
S>3. Дженерики намного удобнее шаблонов, т.к. ты пишешь в уже актуальном коде
Что бы эта фраза имела смысл нужно детерминировать выражение "в уже актуальном коде", так как что такое актуальный код не ясно.
S> и есть ли смысл использовать громоздкие шаблоны
Это не обоснованное утвержедение. Ничего грамоздкого в шаблонах нет. Громоздкость получается когда шаблоны используют не по назначению.
S>при этом необходимо всегда иметь исходный код.
Это конечно аргумент. Аргументом так же яляется и то, что дженирики в дотнете отвечают уловиям компонентного подхода (могут быть скомпилированы в отчуждаемый модуль). Но иного это не нужно. А вот возможности шаблонов очень даже нужны.
Я вот даже подумываю не залудить ли свою версию (расширенную) Шарпа. Добавить туда некоторые недостающие возможности и некую замену шаблонов С++ в виде кода времени компиляции с помощью которого можно будет генерировать код на базе иняормации о типах и внешних источников данных.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> Но это ООП в отличии от шаблонов где генерится новый класс для каждого типа.
S>Дженерики по своей сути это то что я делал раньше только с абстрактной типизацией на этапе конструирования класса.
Дженирики — это дженирики. Полиморфизм — это полиморфизм. То что ты можешь решать одну задачу обоими способами еще не значит, что спостобы идентичны.
Сходства у шаблонов с дженириками куда больше, чем с полиморфизмом. Полиморфизм иногода удобен и полезен. Но для реализации обобщенных алгоритмов куда лучше подходит именно дженерик-парадигма. Шаблоны и есть реализация этой парадигмы для плюсов.
S> Понимаю, что вызвал негодование огромного количества посетителей данного форума но это мое видение и моя позиция.
Да какой гнев? Просто забавно смотреть на зарождение очередного фанатизма.
Я реалист. И вижу что у джеририков проблем хватает. Скорее всего это возрастные проблемы и в будущем они будут устранены. Вот только задолбало ждать этоо долбанное будующее.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
D>>>А что на Дельфи или Шарпе можно пропустить этап "формирования исходнго кода"?
S>> Можно применять уже скомпилированные пакеты или ассемБЛИ и на их основе делать новые классы.
VD>Ну, это и в С++ можно. Есть же lib-ы, да и МС++ существует.
Это по поводу шаблонов, т.к.
VD>Что бы эта фраза имела смысл нужно детерминировать выражение "в уже актуальном коде", так как что такое актуальный код не ясно.
Актуальный код это когда компилятор уже знает расбросал код на составляющие при и ясны связи и типы в отличие от шаблонов где этот этап происходит на этапе компиляции.
И всвязи с этим сообщения об ошибках STL с объемом текста по 3 килобайта и целые книги о том, как надо правильно это сообщения понимать.
VD>Это не обоснованное утвержедение. Ничего грамоздкого в шаблонах нет. Громоздкость получается когда шаблоны используют не по назначению.
Громоздкость заключается в том, что для каждого класса генерится свой код. И при создание шаблона
нужно ориентироваться на конечный исходный код. Хотя это и не проблема при небольших классах но на огромных это может приводить к непредсказуемым ошыбкам. S>>при этом необходимо всегда иметь исходный код.
VD>Это конечно аргумент. Аргументом так же яляется и то, что дженирики в дотнете отвечают уловиям компонентного подхода (могут быть скомпилированы в отчуждаемый модуль). Но иного это не нужно. А вот возможности шаблонов очень даже нужны.
VD>Я вот даже подумываю не залудить ли свою версию (расширенную) Шарпа. Добавить туда некоторые недостающие возможности и некую замену шаблонов С++ в виде кода времени компиляции с помощью которого можно будет генерировать код на базе иняормации о типах и внешних источников данных.
Я лично ничего против шаблонов не имею и как генератор исходников на основании созданного шаблона был бы не против иметь. Иногда нужно дорабатывать под соответствующие типы и иметь возможность наследования. Чем больше инструментов тем только лучше.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>> Но это ООП в отличии от шаблонов где генерится новый класс для каждого типа.
S>>Дженерики по своей сути это то что я делал раньше только с абстрактной типизацией на этапе конструирования класса.
VD>Дженирики — это дженирики. Полиморфизм — это полиморфизм. То что ты можешь решать одну задачу обоими способами еще не значит, что спостобы идентичны.
VD>Сходства у шаблонов с дженириками куда больше, чем с полиморфизмом. Полиморфизм иногода удобен и полезен. Но для реализации обобщенных алгоритмов куда лучше подходит именно дженерик-парадигма. Шаблоны и есть реализация этой парадигмы для плюсов.
Есть очень много вещей где нужно совсещать и полиморфизм и
абстрактную типизацию и дженерики здесь очнь удобны, т.к. практически не отличается от обычного программирования.
Шаблоны тем или иным способом реализуются и в других языках через подстановку типа или Copy-Paste_Replace. Т.К. в С# есть перегрузка операторов то ручная реализация шаблонов достаточно тривиальная задача через исходный код, но для того чтобы не делать лишних телодвижений было бы неплохо иметь генератор исходников на основании шаблонов на уровне компилятора. S>> Понимаю, что вызвал негодование огромного количества посетителей данного форума но это мое видение и моя позиция.
VD>Да какой гнев? Просто забавно смотреть на зарождение очередного фанатизма.
Ну это не фанатизм а реальное удовольствие от дополнительных возможностей реализации собственных мыслей. Это простое проявление восторга.
VD>Я реалист. И вижу что у джеририков проблем хватает. Скорее всего это возрастные проблемы и в будущем они будут устранены. Вот только задолбало ждать этоо долбанное будующее.
Ничего наши дети точно дождуться и программировать будет каждый человек на планете, а не избранные как лет 15 назад.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>> Дело в том что BTCustomLevel содержит общие поля для наследников и поэтому такой подход единственный.
VD>Так не нужно пихать данные в абстракции.
Это почему. На самом деле объяви я их виртуальными с пустой реализацией все нормально??? И зачем мне общие поля переопределять в каждом наследнике???? S>>А зачем городить интефейс если через наследование получаешь более оптимальную структуру класса ??? ООП однако.
VD>И ты еще рассуждаешь об ООП. Интерфейс — это чистая абстракция. Абстрактные класы нужно исключительно для создания частично реализованных классов. Если вдруг появлются такие извраты как у тебя — это верный признак неверного дизайна.
S>>Дженерики по своей сути это то что я делал раньше только с абстрактной типизацией на этапе конструирования класса.
VD>Дженирики — это дженирики. Полиморфизм — это полиморфизм. То что ты можешь решать одну задачу обоими способами еще не значит, что спостобы идентичны.
Можно узнать, в чём же их принципиальное различие?
Ведь дженерик работая с переданным типом, обращается к вполне определённому подмножеству его методов/свойств. Назовём это подмножество интерфейсом, и скажем, что переданный тип реализует этот интефейс. А теперь передадим в бывший дженерик, а теперь обычный класс, это интерфейс — и получим то же самое. Не так ли? Ну да, теперь надо этот интерфейс ещё и описать. Но вряд ли это принципиальное отличие.
Тогда что же?
PS. Естественно, не имею ввиду простые типы. Использование шаблонов на них — действительно удобно.
Здравствуйте, Serginio1, Вы писали:
S> Актуальный код это когда компилятор уже знает расбросал код на составляющие при и ясны связи и типы в отличие от шаблонов где этот этап происходит на этапе компиляции.
Понятнее не стало.
S>И всвязи с этим сообщения об ошибках STL с объемом текста по 3 килобайта и целые книги о том, как надо правильно это сообщения понимать.
Ну, сказки тут рассказвать не надо. Сообщения очень даже понятные.
S> Громоздкость заключается в том, что для каждого класса генерится свой код.
Тебя то это как трогает? Дженирики тоже для каждого вэлью-типа свой код генерируют. Только в рантайме. Ну, и что? Какое это имеет отношение к громоздкости кода? Здается мне, что ты плохо знаешь синтаксис шаблонов. Они по сути мало отличаются.
S> И при создание шаблона S>нужно ориентироваться на конечный исходный код. Хотя это и не проблема при небольших классах но на огромных это может приводить к непредсказуемым ошыбкам.
Какой конечный? Нет никакого "конечного" кода. Есть просто исходный код. Он и в Африке исходным кодом будет.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> Есть очень много вещей где нужно совсещать и полиморфизм и S>абстрактную типизацию и дженерики здесь очнь удобны, т.к. практически не отличается от обычного программирования.
Ну, продемострируй отличие от шаблонов при условии что весь код лежит в одной сборке.
S> Шаблоны тем или иным способом реализуются и в других языках через подстановку типа или Copy-Paste_Replace. Т.К. в С# есть перегрузка операторов то ручная реализация шаблонов достаточно тривиальная задача через исходный код, но для того чтобы не делать лишних телодвижений было бы неплохо иметь генератор исходников на основании шаблонов на уровне компилятора.
Раз тривиальная, то попробуй сделай.
S> Ну это не фанатизм а реальное удовольствие от дополнительных возможностей реализации собственных мыслей. Это простое проявление восторга.
Это он самый форменный и ничем не обоснованный.
S>Ничего наши дети точно дождуться и программировать будет каждый человек на планете, а не избранные как лет 15 назад.
Не что будут делать дети меня не трогает. Мне самому охота при комунизме пожить.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> Это почему. На самом деле объяви я их виртуальными с пустой реализацией все нормально??? И зачем мне общие поля переопределять в каждом наследнике????
Честно говоря объяснять концепции ООП борцам за ООП довольно смешно.
S> Ты немного ошибаешься. Это единственно верный дизайн. А по поводу интерфейсов мне так никто и не ответил на заданный вопрос S>http://www.rsdn.ru/Forum/Message.aspx?mid=410955&only=1
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, alexkro, Вы писали:
A>>А так-же будет поддерживаться смесь templates & generics. Например:
AVK>Ты путаешь МС++ и С++/CLI. Это совершенно разные языки.
Начнем с того, что так называемого MC++ в природе нет. Есть managed extensions. А в Whidbey они будут интегрированы в язык настолько плотно, что называть это managed extensions уже не имеет смысла. Это уже C++ для CLR.
Кстати, Whidbey VC++ будет реализовывать очень большую часть C++/CLI стандарта, а Orcas — весь. Посмотри PDC'шные слайды Саттера по этому поводу.
Здравствуйте, alexkro, Вы писали:
AVK>>Ты путаешь МС++ и С++/CLI. Это совершенно разные языки.
A>Начнем с того, что так называемого MC++ в природе нет. Есть managed extensions.
Я в курсе. Я так же в курсе что под сокращением МС++ большинство подразумевают С++ with managed extensions.
A>А в Whidbey они будут интегрированы в язык настолько плотно, что называть это managed extensions уже не имеет смысла.
В видби кроме поддержки новых фич CLR кардинальных изменений у МС++ не будет.
A> Это уже C++ для CLR.
Тем не менее название осталось прежним.
A>Кстати, Whidbey VC++ будет реализовывать очень большую часть C++/CLI стандарта,
Практически ничего не реализует де-факто и вряд ли что существенно изменится.
A>а Orcas — весь. Посмотри PDC'шные слайды Саттера по этому поводу.
Зачем мне PDC-шные слайды если у меня PDC-шный видби есть.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>> Актуальный код это когда компилятор уже знает расбросал код на составляющие при и ясны связи и типы в отличие от шаблонов где этот этап происходит на этапе компиляции.
VD>Понятнее не стало.
Актуальный код для компилятора в момент редактирования кода. Проверка синтаксиса, подсказки по типам итд.
S>> Громоздкость заключается в том, что для каждого класса генерится свой код.
VD>Тебя то это как трогает? Дженирики тоже для каждого вэлью-типа свой код генерируют. Только в рантайме. Ну, и что? Какое это имеет отношение к громоздкости кода? Здается мне, что ты плохо знаешь синтаксис шаблонов. Они по сути мало отличаются.
Генерится может код работающий только с эти валью типом, но т.к. в самом дженерике напрямую ты можешь только присвоить значение соотвествующего значения или переместить т.е. работа на основании размера тип, то все остальные операции в дженерике связаны только с размером типа (заталкивание в стек, Move, итд). И дополнительного кода может быть очень мало. Это уже зависит от конечной реализации. S>> И при создание шаблона S>>нужно ориентироваться на конечный исходный код. Хотя это и не проблема при небольших классах но на огромных это может приводить к непредсказуемым ошыбкам.
VD>Какой конечный? Нет никакого "конечного" кода. Есть просто исходный код. Он и в Африке исходным кодом будет.
Исходный текст шаблона это не исходный текст готовый для его перевода в Ассемблер.
Все завязываю я с шаблонами. На вкус и цвет товарищей Net.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>> Шаблоны тем или иным способом реализуются и в других языках через подстановку типа или Copy-Paste_Replace. Т.К. в С# есть перегрузка операторов то ручная реализация шаблонов достаточно тривиальная задача через исходный код, но для того чтобы не делать лишних телодвижений было бы неплохо иметь генератор исходников на основании шаблонов на уровне компилятора.
VD>Раз тривиальная, то попробуй сделай.
Чем и занимаюсь долгое время. На основании уже созданного класса с простой подменой. Единственно что в Delphi нет перегрузки операторов, а так это вообще тривиальная задача.
А вот если они внедрят в Delphi.Net то никакого премущесва от сишных шаблонов не останется и следа. Хотя тоже можно делать и C#.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>> Это почему. На самом деле объяви я их виртуальными с пустой реализацией все нормально??? И зачем мне общие поля переопределять в каждом наследнике????
VD>Честно говоря объяснять концепции ООП борцам за ООП довольно смешно.
S>> Ты немного ошибаешься. Это единственно верный дизайн. А по поводу интерфейсов мне так никто и не ответил на заданный вопрос S>>http://www.rsdn.ru/Forum/Message.aspx?mid=410955&only=1
Тогда все дизайны в Delphi и Net ошибочны. Возьмем для примера Stream. А уж других кастомных классов огромное множество, где в базовом классе практически реализована базовая функциональность, но расчитана на перекрытие, реализации абстрактных методов и расширение функциональности в наследниках. А директива abstract говорит лишь о том, что невозможно создать экземпляр этого класса. Кстати ООП у Дельфистов в крови, поэтому переход на C# и Net дается бескровно, особенно гляда на нетовские коипоненты где это практически полные аналоги дельфевых только с расширенными возможностями.
Интерфейсы нужны тогда, когда нужна дополнительная функциональность невозможная при наследовании от базового класса (некий аналог множественного наследования но реализованный на VMT), и работа с интерфейсами это несколько другой подход нежели наследование.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> Актуальный код для компилятора в момент редактирования кода. Проверка синтаксиса, подсказки по типам итд.
Значит ты еще и редактор к ООП припахал.
Комплит ворд это хошо, но к ООП он отношения не имеет.
S> Генерится может код работающий только с эти валью типом, но т.к. в самом дженерике напрямую ты можешь только присвоить значение соотвествующего значения или переместить т.е. работа на основании размера тип, то все остальные операции в дженерике связаны только с размером типа (заталкивание в стек, Move, итд). И дополнительного кода может быть очень мало. Это уже зависит от конечной реализации.
Хрен. Для каждого вэлью типа генерируется всой класс (код). А вот в С++ как раз линкер выкидывает схожие классы подменяя их единой реализацией. Так что выигрыш в размере исполняемого файла можно получить только если дженерик/шаблон используется в разных модулях.
Ну, и главное не нужно подменять понятия. Громоздкость кода может иметь отношение только коду и его объему/читабельности. А в этом аспекте шаблоны мало отличимы от дженириков.
Что же касается размеров модулей... фигня все это. С++-ые длл-ки и ехе-шиники стройны как тополя. Смерть от ожирения им в ближайшее время не грозит. А вот скорость нужна всегда и везде. И тут шаблоны рулят. Будем надяеться, что к выходу релиза дотнета 1.2 он будет соотвествовать спецификации на тот же Шарп 2.0 и при вызовах методов интерфейсов у вэлью-типов не будет произход боксинга (как сейчас). Ну и будем надеяться, что при этом джит сможет инлайнить вызовы таких псевдо-интерфейсов, что позволит получить производительность близкую к той, что достижима на VC 7+.
S> Исходный текст шаблона это не исходный текст готовый для его перевода в Ассемблер.
Тебч что кто-то что-то в ассемблер в ручную заставляет прееводить? Или ты всерьез считашь, что компилятор С++ генерирует промежуточные исходники при компиляции шаблонов? Тогда ты глубоко заблуждаешся.
И вообще, зачем притягивать что-то за уши? Для программиста есть только одни исходники и всем глубого фиолетово как и когда компилятор переводит шаблоны в машинный код. Всех интересует результат. А результатк таков... На стороне шаблонов:
1. Гибкость.
2. Производительность.
На стороне дженириков:
1. Поддрежка технологии Интели-сенс.
2. Распростронение в виде промежуточного кода, а стло быть, возможность использования без наличия исходного кода.
Безспорно и первое и второе достоинство дженириков приятно. Но ключевыми достоинствами обобщенного программироания являются типобезопастность и производительность. А стало быть у С++-ных шаблонов есть некоторый перевес так как производительность у кода созданного с их помощью (при прочих равных) выше.
S> Все завязываю я с шаблонами. На вкус и цвет товарищей Net.
Ты лучше с фанатизмом завязывай. Нужно трезво оценивать реальность.
Дженирики это очень полезный шаг. Но по своим возможностям они пока что уступают шаблонам С++.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> Чем и занимаюсь долгое время. На основании уже созданного класса с простой подменой. Единственно что в Delphi нет перегрузки операторов, а так это вообще тривиальная задача. S> А вот если они внедрят в Delphi.Net то никакого премущесва от сишных шаблонов не останется и следа. Хотя тоже можно делать и C#.
Это говорит только об одно. Ты вообще не представляешь себе возможностей С++-ных шаблонов. Увы разговор с тобой бесполезен.
То о чем ты говоришь в С++ можно сделать с помшью макросов. Возможности же шаблонов простыми реплэйсами не покрываются.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> Тогда все дизайны в Delphi и Net ошибочны.
Кое какие да. Обобщать бы я не стал.
S> Возьмем для примера Stream.
Ага возьми. Открой его дизасемблером и убедись, что он является базовой реализацией. В нем добрая половина методов имеет реализацию.
С другой стороны то, что нет IStream — это явный промох дизайна. Что поделаешь? Драли с ранних версий Явы.
Наличие IStream позволило бы другим делать реализации стрима координально отличные от Stream. Например, можно было бы Сделать обертку над КОМ-овским IStream-ом.
S> А уж других кастомных классов огромное множество, где в базовом классе практически реализована базовая функциональность, но расчитана на перекрытие,
Вот прочти эти строки еще раз... В них суть. Интерфейс — это чистая абстракция. В то время как абстрактный класс — это базовая реализация.
S> Интерфейсы нужны тогда, когда нужна дополнительная функциональность невозможная при наследовании от базового класса (некий аналог множественного наследования но реализованный на VMT), и работа с интерфейсами это несколько другой подход нежели наследование.
Советую почитать какую-нибудь классику по ОО-дизайну и проектированию.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, alexkro, Вы писали:
A>>А так-же будет поддерживаться смесь templates & generics. Например:
AVK>Ты путаешь МС++ и С++/CLI. Это совершенно разные языки.
Есть слухи что в Видби таки включат это дело. Уже сейчас если написать в коде:
String ^ str = new String();
то компилятор орет:
Новый стиль "^" нельзя испосльзовать с ключем /clr:oldStyle.
Так что возможно, что или он уже поддерживается (не документированной опцией), или будет поддерживаться в релизе.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, alexkro, Вы писали:
A>Начнем с того, что так называемого MC++ в природе нет. Есть managed extensions.
Это демагогия.
A> А в Whidbey они будут интегрированы в язык настолько плотно, что называть это managed extensions уже не имеет смысла. Это уже C++ для CLR.
Скажу честно, что это уже не С++. Это уже микс. Причем этот микс как полезен, так и вреден. С одной стороны он упрощает программирование. Но с другой он скрывает реальные действия. Причем делается это нехилыми обертками. Это приведет к значительной потере произовдительности при импользовании нэйтив/цлр-переходов. Старый МС++ показывал все действия так как они будет выглядеть в рельности. Даже боксинг итот был виден. В то же время МС++ останется языком корректный код на котором можно получать только используя кучу код-патернов. Причем кроме как в интеропе, и использовнии унасленованного С/С++-ного кода, реальных приеимуществ в МС++ получить будет нельзя. Единствнное приятное новшество которого не будет в других языках — это детерминированная финализация. Но и она будет всего лишь скрытием патерна IDisposable. МС++ бдет герерить прокси для менеджед-классов хранимых в анменеджед-коде и наоборот.
Так что приемуществ у МС++ по сравнению с Шарпом или Васиком в общем-то не будет.
A>Кстати, Whidbey VC++ будет реализовывать очень большую часть C++/CLI стандарта, а Orcas — весь. Посмотри PDC'шные слайды Саттера по этому поводу.
Пока что компилятор не дает их использовать вообще. По крайней мере не ясно как это сделать. Но намеки есть. По крайней мере компилятор осмысленно ругается на синтаксис описанный на PDC-шных слайдах.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, LaFlour, Вы писали:
LF>Насколько правила женериков для С++ отличаются/подходят к #-вым? LF>Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
Неплохое сравнение templates & generics в C++ приведено в блоге Брандон Брейя (Brandon Bray).
Кстати, там-же немножко про STL.NET (пресловутый stdcli::).
Здравствуйте, alexkro, Вы писали:
AVK>>Зачем мне PDC-шные слайды если у меня PDC-шный видби есть.
A>А за тем, что в Whidbey PDC еще нет тех изменений, которые будут в релизе Whidbey C++.
Очень сомнительно. Тем более что про дату выхода C++/CLI где то упоминалось что в мае 2004 только появиться первая альфа. В это время у Видби во всю будет идти бета-тестирование, а следовательно никаких серьезных изменений не будет.
Здравствуйте, VladD2, Вы писали:
VD>Ага возьми. Открой его дизасемблером и убедись, что он является базовой реализацией. В нем добрая половина методов имеет реализацию.
VD>С другой стороны то, что нет IStream — это явный промох дизайна. Что поделаешь? Драли с ранних версий Явы.
VD>Наличие IStream позволило бы другим делать реализации стрима координально отличные от Stream.
Тебе и сейчас ничего не мешает. В базовом Stream реализованы только асинхронное чтение/запись и ReadByte/WriteByte, которые по сути просто обертки над Read/Write.
VD>Например, можно было бы Сделать обертку над КОМ-овским IStream-ом.
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, alexkro, Вы писали:
AVK>>>Зачем мне PDC-шные слайды если у меня PDC-шный видби есть.
A>>А за тем, что в Whidbey PDC еще нет тех изменений, которые будут в релизе Whidbey C++.
AVK>Очень сомнительно. Тем более что про дату выхода C++/CLI где то упоминалось что в мае 2004 только появиться первая альфа. В это время у Видби во всю будет идти бета-тестирование, а следовательно никаких серьезных изменений не будет.
Здравствуйте, AndrewVK, Вы писали:
AVK>Тебе и сейчас ничего не мешает. В базовом Stream реализованы только асинхронное чтение/запись и ReadByte/WriteByte, которые по сути просто обертки над Read/Write.
Нет батенька, базовая абстракция отсуствует и я уже не могу делать "чистые" реализации. Грамотнее было бы ввести интерфейс, а в Stream реализовать некоторые его методы.
VD>>Например, можно было бы Сделать обертку над КОМ-овским IStream-ом.
AVK>Оно и сейчас вроде как можно.
Сейчас я вынужден отталкиваться от имеющейся реализации.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> А зачем дизасемблером в роторе есть исходники и реализуют он только ассинхронные вызовы.
Да по фигу. Можно и в Роторе.
VD>>С другой стороны то, что нет IStream — это явный промох дизайна. Что поделаешь? Драли с ранних версий Явы.
S> Если объект создан от Stream то передавай его целиком. Если же нужна другая функциональность то просто внедряется класс наследник от Stream и делается импликит на него.
В общем, ты так и не понял.
VD>>Наличие IStream позволило бы другим делать реализации стрима координально отличные от Stream. Например, можно было бы Сделать обертку над КОМ-овским IStream-ом. S> Ком это прошлый век и не стоит на него оборачиваться, а для совместимости с ним в Delphi например есть классы хэлперы TStreamAdapter и TOleStream.
Я тебе говорю о дизайне. Все эти TOleStream — это реализации. Обстракция же одна.
S> Еще раз повторю интерфейсы нужны только для расширения функциональности где простого наследования не хватает. Представь если бы все наследники от Component были реализованы чере IComponent.
А я тебе еще раз повротрю, что интерфейсы — это средство дизайна. И смотреть на них так примитивно не стот.
S> Большое спасибо за совет. Тот же Рихтер говорит, что абстрактные классы предпочтительней там где есть явное наследование и предпочтитель интерфейсы где это невозможно.
Рихтер никогда не занимался дизайном. Он описывает технологии. Наследование же может пригодиться для других целей. Не факт, что не потребуется реализовать поведение описнное в товем абстрактом классе в классе который следовало бы сделать произовдным от другого класса.
Посмотри на коллекции в дотнете. Они все реализуют стандартные интерфейсы.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
AVK>Очень сомнительно. Тем более что про дату выхода C++/CLI где то упоминалось что в мае 2004 только появиться первая альфа. В это время у Видби во всю будет идти бета-тестирование, а следовательно никаких серьезных изменений не будет.
По слухам на PDC показывали версию более-менее поддерживающую эти фичи. Даже эта версия поддерживает чуть-чуть (тот же ^). Так что совершенно реально, что в бэте как раз появится чистично-реализованный C++/CLI.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VD>Посмотри на коллекции в дотнете. Они все реализуют стандартные интерфейсы.
Влад в Моем случае только 2 уровня самый нижний и верхние. Зачем мне там интерфейсы????
Кроме всего прочего кастомный предок имеет общие поля которые легче описать в базовом классе. А поле Child имеет кастомный вид. Эти два вспомогательныз класса больше нигде не будут использоваться кроме их публичного владельца. А уж в приватных классах я как хочу так и ворочу.
По поводу TStreamAdapter он просто оболочка доступа к Stream через интерфейс IStream. Т.К. IStream нужен в СОМ Нужен для совместимости. Хотя классы Delphi и C++ могут использовать абстрактные классы во всяком случае в Delphi 3.
Но абстрактные классы и Интерфейсы не одно и то же.
Ты бы лучше разъяснил разницу интерфейсов в Net и COM. Во всяком случае в Вашем же журнале была статья про интерфейсы и там четко написано, что интерфейсы это ссылка на VMT а в ней хранятся ссылки на функции оболочки которые помоему в EAX запихивают адресс объекта забитый в них и вызывают реальные функции объекта.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
VD>Как миниум тот кому будет нужно сможет сделать чистую реализацию так как он считает нужным.
Может я уже плох совсем но зачем internal классам интерфейсы и интрнальные интерфейсы???? Ведь их никто не видит.
Единственно что мне не хватает в Net это видимости NameSpace, а там уж как хочу так и ворочу.
А вот кому нужно сделать чистую реализацию ( в чем в данном случае я сильно сомневаюсь, что кому то это понадобиться) пусть поступает как я — все переписываю под себя, и практически только очень тяжеловесные классы не трогаю, да и то добавляю нужную функциональность дописывая и изменяя исходники, там где простым наследованием сделать это невозможно.
А сделать класс реализующий аналогичный интерфейс на базе внедренного объекта недолго как тот же TStreamAdapter. Но в данном случае это совсем ненужно и приводить класс к интерфейсу вместо передачи собсвенно класса, так как он является наследником от обявленного.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, Serginio1, Вы писали:
S> Может я уже плох совсем но зачем internal классам интерфейсы и интрнальные интерфейсы????
А почему они должны быть интернал? Их как раз очень даже полезно публичными делать. А для дженериков вообще очень удачным решением является использование интерфейсов, так как тогда можно делать ручные специализации.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, AndrewVK, Вы писали:
AVK>>Тебе и сейчас ничего не мешает. В базовом Stream реализованы только асинхронное чтение/запись и ReadByte/WriteByte, которые по сути просто обертки над Read/Write.
VD>Нет батенька, базовая абстракция отсуствует и я уже не могу делать "чистые" реализации.
Давай все таки не перегибать палку. Кому они нужны, эти псевдочистые реализации, если то что реализовано вобщем то никому ничем не мешает. Просто бесплатный асинхронный доступ и ничего более.
VD> Грамотнее было бы ввести интерфейс, а в Stream реализовать некоторые его методы.
Возможно. Но говорить о том что тебе Stream не позволяет сделать обертку над UCOMIStream по меньшей мере несерьезно.
AVK>>Оно и сейчас вроде как можно.
VD>Сейчас я вынужден отталкиваться от имеющейся реализации.
Нет там никакой реализации, касающейся непосредственно самого стрима. Ты бы вместо того чтобы спорить посмотрел что в Stream реализовано. А то эдак можно докатиться до требования реализации собственного формата VMT.
AVK>>Тебе и сейчас ничего не мешает. В базовом Stream реализованы только асинхронное чтение/запись и ReadByte/WriteByte, которые по сути просто обертки над Read/Write.
VD>Нет батенька, базовая абстракция отсуствует и я уже не могу делать "чистые" реализации. Грамотнее было бы ввести интерфейс, а в Stream реализовать некоторые его методы.
Stream достаточно для всех случаев. Так что грамотнее не плодить лишние сущности.
VD>>>Например, можно было бы Сделать обертку над КОМ-овским IStream-ом.
AVK>>Оно и сейчас вроде как можно.
VD>Сейчас я вынужден отталкиваться от имеющейся реализации.
Что стоит за этими словами "вынужден отталкиваться"? Что конкретно тебе нужно делать и что неправильно?
Вообще, абстрактный класс предпочтительнее интерфейса в том случае, когда нужно обеспечить стандартное поведение для объектов-потомков. Некоторые методы можно сделать виртуальными, а некоторые — просто public, потому что не все методы нужно перегружать. А интерфейсы подобного контроля не дают.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, Serginio1, Вы писали:
S>> Может я уже плох совсем но зачем internal классам интерфейсы и интрнальные интерфейсы????
VD>А почему они должны быть интернал? Их как раз очень даже полезно публичными делать. А для дженериков вообще очень удачным решением является использование интерфейсов, так как тогда можно делать ручные специализации.
Честно говоря хотел их сделать вообще внутри основного класса, т.к. это вспомогательные классы, но т.к. еще рука не набита то вынес их по обыкновению в NameSpace. На самом то деле это вообще приватные классы и кроме их владельца никто их видеть и использовать напрямую и не должен. Просто в Delphi внутри NameSpace видимы все поля, а в Net ограничение сборкой, что неудобно когда используешь исходник и переделываешь его под себя, а отдельную сборку под него как то не очень то и хочется городить, т.к. это одноразовое решение.
и солнце б утром не вставало, когда бы не было меня
Re[17]: Generic в C# и C++?
От:
Аноним
Дата:
25.11.03 11:50
Оценка:
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, Serginio1, Вы писали:
VD>>>Как миниум тот кому будет нужно сможет сделать чистую реализацию так как он считает нужным.
S>> Может я уже плох совсем но зачем internal классам интерфейсы и интрнальные интерфейсы????
AVK>А кто говорил про internal интерфейсы? Суть в том что ты предоставляешь свой класс, реализующий вобщем то обобщенную функциональность без какой либо возможности заменить его на свою реализацию, что есть кривой дизайн. Базовый класс вполне может быть internal, но вот интерфейс обязательно должен быть паблик.
Да это вообще приватные классы и доступ к ним извне не нужен.
Это сыр бор тянется от http://www.rsdn.ru/Forum/Message.aspx?mid=447720&only=1
Здравствуйте, mihailik, Вы писали:
M>Кроме того, возможности генериков существенно ограничены синтаксисом. Слава богу, хоть в C# гениальные провидцы (вроде Александреску) не будут делать из наших мозгов котлету.
AVK>Где было ясно написано AVK>public class BTIndexPP<K,V>
Правильно, только
internal abstract class BTCustomLevel<K,V>
internal sealed class BTNullLevel<K,V>: BTCustomLevel<K,V>
internal sealed class BTParentLevel<K,V>: BTCustomLevel<K,V>
BTIndexPP<K,V> класс используе внутри себя и
public class BTIndexPP<K,V>
{
internal IKeyComparer<K> Comp;
internal BTCustomLevel<K,V> Ind; /// !!!!
internal BTNullLevel<K,V> NullLevel; // !!!!
internal int RecordCount;
internal NullItem<K,V> NullItemAsNull;
Здравствуйте, AndrewVK, Вы писали:
AVK>Здравствуйте, alexkro, Вы писали:
AVK>>>Зачем мне PDC-шные слайды если у меня PDC-шный видби есть.
A>>А за тем, что в Whidbey PDC еще нет тех изменений, которые будут в релизе Whidbey C++.
AVK>Очень сомнительно. Тем более что про дату выхода C++/CLI где то упоминалось что в мае 2004 только появиться первая альфа. В это время у Видби во всю будет идти бета-тестирование, а следовательно никаких серьезных изменений не будет.
Здравствуйте, mihailik, Вы писали:
M>А как это вообще можно реализовать?
Это ты у кого спрашиваешь? Я его не реализую. Открой стандарт на Шарп 2.0 и прочти пунк "20.7.3. Type parameters and boxing"
M>1. Физически в структуре нет метаданных, только поля. Как её без "обёртывания" можно в интерфейс превратить?
Причем тут метаданные? Вызов функции интерфейса — это вызов по указателю. Если внутри метода не лезть к ОО-модели, то его спокойно можно заменить на прямой вызов.
Так как вэлью-типы принципиально унаследованы только от System.Object, да и то виртуально, то нет особых проблем делать прямой вызов вместо вызова интерфейса. Внтури вэлью-типов все вызовы к методам обжекат оптимизируются и делаются не виртуально. Значит и другие можно соптимизировать.
Пока что происходит боксинг. Но в стандарте уже четко записано, что его не будет. Вопрос только в том, не соврут ли.
M>2. Кто будет боксить при вызове ToString на интерфейсе, полученном от структуры?
А он и так не боксится. Просто закладваюет адрес переменной из стека и делают вызов. Декомпилируй подобный код и убедись сам.
M>Кроме того, возможности генериков существенно ограничены синтаксисом. Слава богу, хоть в C# гениальные провидцы (вроде Александреску) не будут делать из наших мозгов котлету.
Котлету делают в виду того что в языке нет нужных возможностей. К сожалению в шарпе тоже кое чего нет. И отсуствие возможностей что есть в шаблонах ставят крест на рсширении языка всеми кроме МС.
Потом у шаблонов было очень удобное применение и без Александревсковских наворотах. Вернее без его наворотов в области метапрограммирования. Та же идея полиси-бэйзед-классов я лично с удовольствием применял. В дотнете для организации подобных фич придется пользоваться нартайм-кодом и виртуальными вызовами. А это тормоза и блее громоздкий код. Ничего хорошего в этом нет.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
AVK>Давай все таки не перегибать палку. Кому они нужны, эти псевдочистые реализации, если то что реализовано вобщем то никому ничем не мешает. Просто бесплатный асинхронный доступ и ничего более.
А я и не перегибаю. Чем бы помешал интерфейс в данном случае? Был бы и интерфейс и базовый абстрактый класс.
AVK>Возможно. Но говорить о том что тебе Stream не позволяет сделать обертку над UCOMIStream по меньшей мере несерьезно.
Я эту обертку могу сделать из без Stream. Вопрос в том, что если мне по каким-то причинам неподойдет реализация от МС, я не смогу применять все что использует Stream. А промазать при разработке Stream и сделать нечто кривенькое очень просто. То что Stream не взывает проблем это счастливое совподение. Обратных вариантов тоже придостаточно.
AVK>Нет там никакой реализации, касающейся непосредственно самого стрима. Ты бы вместо того чтобы спорить посмотрел что в Stream реализовано. А то эдак можно докатиться до требования реализации собственного формата VMT.
Факт в том, что там уже что-то реализовано. И нет никакой гарантии, что это что-то не окажется лишним/вредным.
Дело не в конкретном случае. Дело в принципе. Если ты делаешь некую абстракцию — не соеденяй ее с реализацией. Пусть даже абстрактной и насквозь виртуальной. Иначе рано или поздно наступишь на грабли кривого дизайна.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, mihailik, Вы писали:
M>Вообще, абстрактный класс предпочтительнее интерфейса в том случае, когда нужно обеспечить стандартное поведение для объектов-потомков. Некоторые методы можно сделать виртуальными, а некоторые — просто public, потому что не все методы нужно перегружать. А интерфейсы подобного контроля не дают.
Есть понятие интерфейс и его контракта. Любое смешивание интерфейса и реализации — это потенциальное зло.
Очень жаль, что дотнет это дупускает. Тем самым сделан шаг назад по сравнению с Корбой и КОМ-ом.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
S>>пусть поступает как я — все переписываю под себя,
AVK> AVK>Вот это обычно и называют кривым дизайном.
Именно. Только это не смешно. Смешно то что людям нужно объяснять такие простые истины.
А результат обычно заключается в том, что из-за мелкой фигни нужно лезть через рефлекшон к закрытым членам или вообще отказываться от использования того или иного кода из-за того, что нельзя заменить маленькую фитюльку.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> Правильно, только S>internal abstract class BTCustomLevel<K,V>
Вот это и есть кривой дизайн. Если это скрытые классы реалзиации, то зачем их вообще делать абстрактными? И почему нет общей асбтракции которую можно переопределить?
В итоге люди воспользовавшиеся твоим классом будут на него намертво завязаны. А из-за неоправданной виртуальности будет страдать производительность.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, <Аноним>, Вы писали:
А>> Да это вообще приватные классы и доступ к ним извне не нужен.
VD>Какие приватные? Ты интерфейс вооей коллекции описал как асбтрактый класс с членами. О чем речь то?
В том то и дело, что не писал я интерфесы колекций. Это не всегда и нужно, как DBTable, но если нужно то прикрутить на public методах недолго. Просто этот вариант с абстрактны классом нужен для того что нижняя ветвь (Child) может быть самой нижней где хранятся данные или родительский подуровень. Так же у IndexBTPP Root может быть как NullLevel или ParentLevel. Просто на разных уровнях хранятся разные данные и по разному обрабатываются. И нужна только внутри всех этих трех классов для внутренней функциональности.
Там кстати ошибка в кастомный класс не нужно вводить поле Child оно только у ParentLevel.
Вот и речь о том, что говорим о другом. А просто показал пример наследования в дженериках, и то что они ни чем не отличаются от обычных классов.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, AndrewVK, Вы писали:
AVK>Отсутствие гарантии правильной реализации асинхронных операций.
Ну, это не серьезно. Любая реализация может быть как нормальной, так и глючной.
AVK> Т.е. сам интерфейс конечно не помешал бы, но при использовании в своих классах я бы наружу выставлял запрос именно Stream а не IStream, поскольку это надежнее,
Вот это уже глупость. При наличии абстракции указывать специализацию нельзя.
AVK> а в плане гибкости ничего на практике не меняется.
Вот указав базовую (минимально подходящую) абстракцию ты точно ничего не теряешь. В обратном случае ничего гарантировать нельзя.
AVK>Давай конкретно — по каким причинам тебе может не подойти конкретно Stream.
А не нужно конкретнее. Это общее правило и его нужно просто применять. Оно просто гарантирует отсуствие граблей.
AVK>Точно так же факт что много чего реализовано в CLR, JIT и "нет никакой гарантии, что это что-то не окажется лишним/вредным".
Это разные вещи. Но гибкость никогда не помешает. Тот же С++ народ любит не за его складность и не противоричивость, а за то, что на нем можно исправить/добавить разные возможности.
AVK> Делать абстрактным все и вся это другая крайность, которая тоже ни к чему хорошему не приведет.
Я как бы не призываю делать все абстрактым. Но если уж делается абстракция, то лучше делать ее по всем правилам, а не лепить горбатого.
Так, например, для скрытых классов реализации абстракция вообще не нужна.
AVK> Нужно выбирать золотую середину — где то базовые классы, где то интерфейсы.
Нужно думать и принимать конкретные решения для конкретных случаев, а не выбирать середину. Но правила примененные с умом еще никому не мешали.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> В том то и дело, что не писал я интерфесы колекций.
1. Зря.
2. Зачем тебе вообще тогда понадобились абстрактные классы?
S> Это не всегда и нужно,
У тебя точно нужно.
S> как DBTable,
Не нужно пенять на то что не доконца понимаешь. DBTable — это частичная реализация разширяющая другую (причем конкретную) реализацию — DataTable. А вот DataTable рализует базовую абстракцию IListSource.
S>но если нужно то прикрутить на public методах недолго.
Блин. Тебе и говорят — что это кривейший дизайн. Ты пользуешся средствами совершенно не по назначению. public-методы и так не трудно сделать реализую интерфейс публичными методами. А вот отсуствие базовой абстракции приведет к тому, что люди взявшие твой класс будут скованны и не смогут его как следует развивать.
S> Просто этот вариант с абстрактны классом нужен для того что нижняя ветвь (Child) может быть самой нижней где хранятся данные или родительский подуровень. Так же у IndexBTPP Root может быть как NullLevel или ParentLevel. Просто на разных уровнях хранятся разные данные и по разному обрабатываются. И нужна только внутри всех этих трех классов для внутренней функциональности. S> Там кстати ошибка в кастомный класс не нужно вводить поле Child оно только у ParentLevel.
Проблема в том, что твой код довольно трудно читать. Да и алгоритмы в нем не примитивные. Давай поступим так. Ты опишешь работу (алгоритм и реализацию) своего класса в небольшой статейке. Я это дело прочту (ну, подправим если что не так...) и постораюсь сделать "правильный" (с моей точки зрения) вариант. А потом сравним все за и против. Ну, и за одно получим интересную статью и проверенную реализацию.
S> Вот и речь о том, что говорим о другом. А просто показал пример наследования в дженериках, и то что они ни чем не отличаются от обычных классов.
Ты показал плохой пример. Абстрактый класс без реализации — это явно кривой дизайн. Да и скрытые абстракции тоже скорее всего плохой подход. Как минимум виртуальные методы тормозят.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
AVK>>Отсутствие гарантии правильной реализации асинхронных операций.
VD>Ну, это не серьезно. Любая реализация может быть как нормальной, так и глючной.
Это серьезно. И дело не в глючности, а в гарантии определенных особенностей внутреннего поведения этих методов.
AVK>> Т.е. сам интерфейс конечно не помешал бы, но при использовании в своих классах я бы наружу выставлял запрос именно Stream а не IStream, поскольку это надежнее,
VD>Вот это уже глупость. При наличии абстракции указывать специализацию нельзя.
Глупость это пихать полную абстракцию ака интерфейс куда не попадя, даже туда где он не нужен.
AVK>>Давай конкретно — по каким причинам тебе может не подойти конкретно Stream.
VD>А не нужно конкретнее.
Нужно, иначе все рассуждения становятся высосанными из пальца. Все таки программирование это больше техническая дисциплина, нежели философская и рассуждать о высших материях конечно интересно, но в конечном итоге нужно все таки ехать.
AVK>>Точно так же факт что много чего реализовано в CLR, JIT и "нет никакой гарантии, что это что-то не окажется лишним/вредным".
VD>Это разные вещи.
Это те же самые вещи, вопрос только в их уровне абстракции, не более того.
VD> Но гибкость никогда не помешает.
Очень спорное утверждение.
VD> Тот же С++ народ любит не за его складность и не противоричивость, а за то, что на нем можно исправить/добавить разные возможности.
Личные проблемы любящего народа. Я лично страстной любовью ни к какому языку не пылаю, поскольку любовь к онному напоминает любовь к молотку или рубанку.
AVK>> Делать абстрактным все и вся это другая крайность, которая тоже ни к чему хорошему не приведет.
VD>Я как бы не призываю делать все абстрактым.
Именно это ты и делал несколькими строчками выше. Мол мне конкретика пофигу, это общее правило.
VD>Так, например, для скрытых классов реализации абстракция вообще не нужна.
Напомню — разговор об IStream. Все остальные случаи меня не интересуют в данный момент.
AVK>> Нужно выбирать золотую середину — где то базовые классы, где то интерфейсы.
VD>Нужно думать и принимать конкретные решения для конкретных случаев,
Золотые слова, только почему то противоречат тому что ты только что писал.
VD> а не выбирать середину.
Выбирать середину это и есть "думать и принимать конкретные решения для конкретных случаев".
VD> Но правила примененные с умом еще никому не мешали.
S>> Вот и речь о том, что говорим о другом. А просто показал пример наследования в дженериках, и то что они ни чем не отличаются от обычных классов.
VD>Ты показал плохой пример. Абстрактый класс без реализации — это явно кривой дизайн. Да и скрытые абстракции тоже скорее всего плохой подход. Как минимум виртуальные методы тормозят.
Постараюсь написать более подробно. Но смысл таков, что за каждый уровень Б++ дерева отвечает класс, для выстроения его в нужном порядке, так как страници не имеют родителя иначе бы приходилось менять их при каждом переносе элементов с одной страници на другую. Но самый нижний уровень имеет отличную реализацию, т.к. хранятся другие данные нежели на верхних уровнях. На в каждой странице хранится счетчик количества элементов и разные массивы: в одном Key,Child а на нижнем Key,Value. В промышленнм стандарте Child и Value это инты и можно обойтись без абстрактных классов передавая только эти инты и в зависимости от уровня вызывать тот или иной метод, но на самом деле виртуальные методы не сильно и тормозят т.к. методы не хилые и о инлайне нет и речи, а т.к. уровней мало то все ссылки на методы сидят в кэше и скорость действительно очень приличная и полностью с применением ООП.
А о плохом дизайне тогда посоветуй как сделать лучше, а я постараюсь объяснить как с могу, но на самом деле очень сложно объяснять в оофлайне. Алгоритм на самом деле простой правда со многими заморочкам но делается за день — два и объяснить с глазу на глаз очень просто и понадобится всего около часа, а затем можно разработать методику описания принципа данного алгоритма.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, LaFlour, Вы писали:
LF>Насколько правила женериков для С++ отличаются/подходят к #-вым? LF>Ну синтаксис и прочее что писал Алексадреску и Джосуттис, насколько они адекватны в свете #вых женериков?
А вот еще повод к размышлению...
При инстанциировании параметризованного класса на C++ компилятор генерит код только для тех методов класса, которые используются (не хочу тут разводить лишнего формализма:) Это позволяет создавать классы, функциональность, которых расширяется (или сужается) в зависимости от значения параметра шаблона.
При этом не проблема, если в классе Strategy в нужный момент не окажется функции f. Просто обломится компиляция.
В связи с тем, что generic'и являются сущностью времени выполнения они не могут предоставлять такую же гибкость. Тут у m$ явно случилась проблема. Но они нашли вполне концептуальное решение. Вместо того, чтобы ожидать, что у параметра шаблона будет наличествовать некий метод, проще сразу потребовать, чтобы параметр шаблона принадлежал некому типу. И это правильно. Но япона мать! Какой же уродский синтаксис для этого выбран! (эмоции...)
public class LinkedList<K,T> where K : IComparable<K>
скопировано из technical article c m$.com
выделенный жирным шрифтом кусок — типичное паскалевское утверждение о том, что K имеет тип IComparable. Кто там у них из delhi в .net пришел? Запамятовал...
Также обошлись и с конструкторами по умолчанию.
Примеры на VB даже смотреть страшно
А вот еще интересный момент.
Дженерик не может унаследоваться от своего параметра a la
template <class T> class A : public T
Вообще, зачем были введены generic'и в .net? Какая преследовалась цель?
Еще вопрос: в каком состоянии находится .net в отношении комитетов по стандартам? Если он все еще принадлежит m$, то это очень прискорбный факт... Потому что они уже сделали, что смогли, а сейчас начнутся извращения...
Что скажет благородная публика?
Здравствуйте, outsourcer, Вы писали:
O>В связи с тем, что generic'и являются сущностью времени выполнения они не могут предоставлять такую же гибкость. Тут у m$ явно случилась проблема. Но они нашли вполне концептуальное решение. Вместо того, чтобы ожидать, что у параметра шаблона будет наличествовать некий метод, проще сразу потребовать, чтобы параметр шаблона принадлежал некому типу. И это правильно. Но япона мать! Какой же уродский синтаксис для этого выбран! (эмоции...)
O>
O>public class LinkedList<K,T> where K : IComparable<K>
O>
O>скопировано из technical article c m$.com
O>выделенный жирным шрифтом кусок — типичное паскалевское утверждение о том, что K имеет тип IComparable. Кто там у них из delhi в .net пришел? Запамятовал...
O>Также обошлись и с конструкторами по умолчанию.
Даже обидно как-то. В Jave'e к этому делу подошли более элегантно.... В жаве типизация параметра шаблона происходит в угловых скобках ( как и должо быть по человечески, на мой взгляд )
AVK>У DataTable есть интерфейс, IListSource. Кроме того DataTable это всего лишь часть коллекции. Другая часть, DataView , реализует IList, IBindingList, ITypedList.
S>> но если нужно то прикрутить на public методах недолго.
AVK>Тебе недолго. А тому кто будет этим пользоваться просто невозможно. Кроме того просто прикрутить интерфейс недостаточно, необходимо еще и сменить на интерфейс все внешние ссылки.
Согласен. Но все листы очень убоги и не раскрывают всех возможностей, а обеспечить функциональность этих интефейсов недолго. Речь пока идет о функциональности Б++ дерева, а все изыски могут немного подождать и реализовать ввиде оберток вокруг существующей реализации.
и солнце б утром не вставало, когда бы не было меня
Здравствуйте, AndrewVK, Вы писали:
AVK>Это серьезно. И дело не в глючности, а в гарантии определенных особенностей внутреннего поведения этих методов.
Это не просто не серьезно. Это демагогия. Уж извини.
AVK>Глупость это пихать полную абстракцию ака интерфейс куда не попадя, даже туда где он не нужен.
И кто пихает куда ни попадя? В стриме интерфейс нужен. В классе реализующем универсальную структуру данных вроде Б+-дерева — тоже. Или ты не согласен?
VD>> Но гибкость никогда не помешает.
AVK>Очень спорное утверждение.
Ну, раз ты споришь...
AVK>Личные проблемы любящего народа. Я лично страстной любовью ни к какому языку не пылаю, поскольку любовь к онному напоминает любовь к молотку или рубанку.
Смешно. Твои высказывания по тому же С++ говорят об обратном.
Проблемы же это не "любящего народа", а наши. Так как Шарп той же гибкостью не обладает (к сожалению).
VD>>Я как бы не призываю делать все абстрактым.
AVK>Именно это ты и делал несколькими строчками выше.
Не нужно песен. Я призываю не делать половинчатых решений. Если уш делается абстракция, то пусть она делается чистой.
AVK> Мол мне конкретика пофигу, это общее правило.
Вот только в этом правиле нет призыва все делать абстрактным. Так что н надо ля-ля.
VD>>Так, например, для скрытых классов реализации абстракция вообще не нужна.
AVK>Напомню — разговор об IStream. Все остальные случаи меня не интересуют в данный момент.
Напомню, изначально назговор о применении abstract в классах Серджинио1.
AVK>Золотые слова, только почему то противоречат тому что ты только что писал.
Ничему они не противоречат. Необходимость думать не противоречит наличию правил.
VD>> а не выбирать середину.
AVK>Выбирать середину это и есть "думать и принимать конкретные решения для конкретных случаев".
Тогда мы по разному понимаем слова "выбирать середину".
VD>> Но правила примененные с умом еще никому не мешали.
AVK>Вот именно что с умом.
Я где-то их применял бездумно?
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Serginio1, Вы писали:
S> А о плохом дизайне тогда посоветуй как сделать лучше,
Еще раз повторяю. Создай небольшую статейку объясняющую что и как. Тогда я постораюсь помочь, так как буду понимать что у тебя и зачем. Без этого на разбирательства уйдет очень много времени. Ну, и за одно убьем двух зайцев, так как создадим статью которую будет не грешно опубликовать в журнале и на сайте.
В эту статью хорошо бы включить описания и других твоих реализаций. Я как раз сейчас пишу статью о коллекциях в дотнете. Твоя статья стала бы прекрасным дополнением, так сказать для "продвинутых".
Только не выкладывай все сразу в конфу. Должна же быть какая-то эксклюзивность.
S> а я постараюсь объяснить как с могу, но на самом деле очень сложно объяснять в оофлайне.
Ты пиши. Я поправлю все что нужно. Главное, чтобы была четко сформулирована идея.
S> Алгоритм на самом деле простой правда со многими заморочкам но делается за день — два и объяснить с глазу на глаз очень просто и понадобится всего около часа, а затем можно разработать методику описания принципа данного алгоритма.
Ну, тода давай сделаем в два этапа. Сначала опишешь как сможешь. Потом объяснишь лично. А потом я поправлю первый вариант и получится интересная и нужная статья.
... << RSDN@Home 1.1.2 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
AVK>>Это серьезно. И дело не в глючности, а в гарантии определенных особенностей внутреннего поведения этих методов.
VD>Это не просто не серьезно. Это демагогия. Уж извини.
Как знаешь.
AVK>>Глупость это пихать полную абстракцию ака интерфейс куда не попадя, даже туда где он не нужен.
VD>И кто пихает куда ни попадя? В стриме интерфейс нужен.
Зачем?
VD> В классе реализующем универсальную структуру данных вроде Б+-дерева — тоже. Или ты не согласен?
С первым нет, со вторым да.
AVK>>Личные проблемы любящего народа. Я лично страстной любовью ни к какому языку не пылаю, поскольку любовь к онному напоминает любовь к молотку или рубанку.
VD>Смешно. Твои высказывания по тому же С++ говорят об обратном.
Цитаты в студию.
AVK>> Мол мне конкретика пофигу, это общее правило.
VD>Вот только в этом правиле нет призыва все делать абстрактным.
Общее правило, в котором не указано когда его применять означает что применять надо всегда.
AVK>>Напомню — разговор об IStream. Все остальные случаи меня не интересуют в данный момент.
VD>Напомню, изначально назговор о применении abstract в классах Серджинио1.
По поводу его классов я уже высказался. То же письмо, на которое ты ответил было по поводу твоего высказывания на тему Stream.
VD>>> а не выбирать середину.
AVK>>Выбирать середину это и есть "думать и принимать конкретные решения для конкретных случаев".
VD>Тогда мы по разному понимаем слова "выбирать середину".
Здравствуйте, VladD2, Вы писали:
AVK>>Тебе и сейчас ничего не мешает. В базовом Stream реализованы только асинхронное чтение/запись и ReadByte/WriteByte, которые по сути просто обертки над Read/Write. VD>Нет батенька, базовая абстракция отсуствует и я уже не могу делать "чистые" реализации. Грамотнее было бы ввести интерфейс, а в Stream реализовать некоторые его методы.
Кстати, из презентации ADO.NET 1.2:
ADO.NET v1.0/1.1 was based on interfaces
Not enough to write provider-agnostic code
Hard to evolve
We’re introducing a common model
Abstract base classes instead of interfaces
Better versioning story
3rd party providers can reuse our common code
They can even re-use our connection pooler
Provider-independent apps fully enabled at the API level
This is an extension, no breaking changes
Кроме того, в ATL обычной практикой являются классы IXXXImpl, реализующие некую дефолтную функциональность интерфейса. В .NET это не так удобно из-за отсутствия множественного наследования (Control.ActiveXImpl — типичный пример такой проблемы), но для классов с одним основным интерфейсом вполне оправдано.
Здравствуйте, VladD2, Вы писали:
VD>Против дефолтной реализации я лично ничего не имею. Я против зависимости от какй бы то нибыло реализации.
Кстати, у базовых классов есть еще одно преимущество перед интерфейсами. Если в следующей версии захочется добавить новый метод, скажем, DataTable DbConnection.GetSchema() или bool DataAdapter.ReturnProviderSpecificTypes (реальные примеры из 1.2), то в базовый класс он добавляется без проблем — пишется дефолтная реализация, кидающая exception или эмулирующая его через другие методы, и все существующие third-party провайдеры продолжают рабаоать без перекомпиляции. Если же дизайн основан на интерфейсах, то приходится плодить уродцев типа IDbConnection2 и IDataAdapter2.