Здравствуйте, AndrewVK, Вы писали:
AVK>Двойка тебе за знание адонета . Чтобы создать команду нет необходимости открывать коннекшен, открывать нужно только для Execute, Prepare и BeginTransaction.
А какая разница когда его открывать?
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
AVK>При желании в том подходе, пример которого приведен можно наворотить такие извратства, что плюсам и не снились, только вот нафик никому это не нужно.
Да нужно. И подход твой дико не удобный и не производительный. Так что шаблоны нужны. Другое дело, что не досмерти. В принципе можно и без них. А учитывая, что они скоро появятся...
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, desperado_gmbh, Вы писали:
_>Этот код нетипобезопасен — если написать C2: public C1<C3> или вызвать C1::Method1 из конструктора C1, то возникнет неопределенное поведение.
Ну, C3 бесспорно. Можно правда обезопаситься делая не статик-каст, а динамик-, но это уже медленнее. А насчет вызова метода из коструктора ты ошибаешся. Тут все будет ОК.
_>С использованием generics аналогичный код будет выглядеть примерно так:
_>
_>interface ISomeUniversalWork
_>{
_> int SomeUniversalWork();
_>};
_>class C1<T> where T : ISomeUniversalWork {
_> public void Method1() {
_> int i = ((T)this).SomeUniversalWork();
_> }
_>}
_>class C2 : C1<C2>, ISomeUniversalWork
_>{
_> int ISomeUniversalWork.SomeUniversalWork() {
_> return 0;
_> }
_>};
_>
Не. Не прокатит. Если отнаследовался от интерфейса, то обязан реализовать метод. Так что проще или виртуальную функцию или так же динамик-кстом. Он в шарпе работает неплохо.
_>При текущей реализации generics приведение (T)this будет съедать весь эффект от невиртуальности, но в принципе никто не мешает будущей версии компилятора сынлайнить все это до нужного состояния.
Напомнь, что реализации generics для дотнета пока вообще нет в природе. Это ты говоришь о gyro, а это совсе не то, что будет в дотнете.
На счет тормозов. Да такое приведение будет динамик-кастом и скорость будет ниже. Но ведь можно делать приведение один раз и запоминать указатель в скрытом поле. При этом будет производиться или thiscall, или инлайнинг.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, desperado_gmbh, Вы писали:
_>Фитюлька написана с соблюдением типобезопасности.
Та на объем и уродливость кода посмотри. А ведь если в языке сделать одну поправку... вернее даже допущение, то можно было бы обойтись одной строчкой. А допущение очень простое. Соотвествие указателей на методы нужно проверять без учета типа (только на базе формального описания метода).
_> Если хочешь показать reinterpret_cast или static_cast на потомка в реализации сигналов — дерзай, исходники доступны. Я знаю одно такое место — static_cast внутри any_cast, но он сделан для увеличения производительности (как, скажем, некоторые unsafe методы класса String) и может быть безболезненно заменен на dynamic_cast.
Я не хочу показать на типобезопастность. Я хочу показать на уродливость и огромность кода для решения примитивной задачи. Еще раз повторюсь, что если наплевать на типбезопастность, тоже самое делается в 3-10 строк кода.
_>Да. Шаблоны задумывались для тех же целей, что и generics сейчас, но оказалось, что на них можно сделать гораздо больше.
Кто бы спорил. Я года три назад с удовольствием писла разные смарт-враперы. И видимо еще займусь этим на Шарпе...
_> Вообще c++ — омерзительный язык, и я, если мне дадут такую возможность, вместо порта ado.net на плюсы лучше бы писал что-нибудь на c#, смирив гордыню и наплевав на шаблоны, дожидаясь generics. Но 700 строк реализации шести вложенных в System.Windows.Forms.ListView коллекций не дали мне сегодня спать до трех часов ночи...
Что-то я не понял, какое отношение имеют строки из System.Windows.Forms.ListView к ado.net? Это ты о чем? И причем тут С++ и Шарп?
Кстати, о реализации коллекций. Я тут как-то писал парсер дотнетных метаданных (напрямую из PE-файла). Взял МС++ и с помощью... не не шаблонов, а макросов создал атоматическую герерилку кода по описаниям в стиле мапов (из MFC/ATL). Получилось красиво, элегантно, производительно и главное (!) офигительно быстро (в смысле скорость кодирования). Правда с отладкой потрахался. При этом получившийся код прекрасно работает как в менеджед режиме (под тем же Шарпом), так и в обычном анмэнеджед (под MFC). И ведь хрена с два это можно сделать на баблонах.
_>Кстати, раскрою секрет: на шаблонах невозможно сделать аналог делегатов с произвольным числом параметров. Для каждого n от 0 до 10 есть шаблон делегата с n параметрами, а потом они приведены в общий вид с помощью макросов
Это можно решить передавая массив.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, AndrewVK, Вы писали:
AVK>Да начерта их эмулировать? Это самоцель что ли?
Дык удобнее с ними. Ты сам попробуй на Шарпе пописать без делегатов...
AVK> Главное — обеспечить удобный простой и лаконичный типизированный оо колбек, а уж как это обеспечивать второй вопрос.
Дык вот в С++ это реализуется только страшнейшими извращениями с шаблонами. Приемущество Шарпа над С++ в том, что часто используемые вкусности в язык уже встроены. А С++ над Шарпом, в том, что на Шарпе нельзя так же извратиться, чтобы реализовать отсуствующие в языке фичи. Про геренацию кода говорить не будем, так как это намного большее извращение.
AVK> Делегаты — неплохое приближение к идеалу, но совершенно точно еще не идеал. С введением к примеру анонимных методов станет все еще интереснее.
Я кстати, так и не просек в чет тут кайф.
AVK>Ну тут даже без шаблонов проблем достаточно. Небольшой TreeGridBase компилируется в разы дольше чем весь остальной янус, и это при том что компилер шарпа 1 версии, а плюсов 7.
Да он по сравнению с нашими проектами компилируется моментально. К тому же шарп изначально спроектрован на компонентную сборку, а С++ на включение исходных файлов. Это надо сказать тоже неприятное наследие. В принципе, если делать чисто CLS-совместимый проект, он будет компилироваться не намного дольше Шарповского. Кстати, библиотека читающая метаданные компилируется как в менеджед-, так и в анменеджед-варианте. Так вот в анменеджед она компилируется в 1.5 раза дольше. Но это видимо из-за того, что в дотнете часть компиляции переносится в рантайм.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Я не хочу показать на типобезопастность. Я хочу показать на уродливость и огромность кода для решения примитивной задачи. Еще раз повторюсь, что если наплевать на типбезопастность, тоже самое делается в 3-10 строк кода.
Не выйдет. Если делегат вызван с несколькими параметрами, то их надо передать в каждй вызов лежащих в нем колбеков, для чего надо знать их типы. Ассемблерная вставка тоже не пройдет — хочется передавать параметры и с нетривиальным конструктором копирования.
_>> Вообще c++ — омерзительный язык, и я, если мне дадут такую возможность, вместо порта ado.net на плюсы лучше бы писал что-нибудь на c#, смирив гордыню и наплевав на шаблоны, дожидаясь generics. Но 700 строк реализации шести вложенных в System.Windows.Forms.ListView коллекций не дали мне сегодня спать до трех часов ночи... VD>Что-то я не понял, какое отношение имеют строки из System.Windows.Forms.ListView к ado.net? Это ты о чем? И причем тут С++ и Шарп?
На работе я порчу ado.net на плюсы, а дома дизассемблирую windows forms. Шесть наследников IList по 100 строк, у которых отличается максимум треть кода, — это ужасно.
_>>Кстати, раскрою секрет: на шаблонах невозможно сделать аналог делегатов с произвольным числом параметров. Для каждого n от 0 до 10 есть шаблон делегата с n параметрами, а потом они приведены в общий вид с помощью макросов VD>Это можно решить передавая массив.
То есть сведя к ситуации с одним параметром. Я тоже не возьму буст, а буду делать в своем плюсовом проекте делегаты только с двумя параметрами — sender и eventargs.
Здравствуйте, VladD2, Вы писали:
AVK>>Можно, вот только результатом этого как раз и являются вопли о неправильности шарпа.
VD>Не надо песен. Шарп и в правду не совершенен.
А про совершенство никто и не говорил. Но вопли то вроде того что шарп полная туфта по сравнению с С++.
VD>И большинство воплей по делу, если конечно это не простое фанатство.
Здравствуйте, VladD2, Вы писали:
AVK>>Да? И ты берешься сделать к примеру класс с МН менеджед?
VD>Легко. Компилируются даже шаблонные навароты ATL-я.
Нет, gc-классы не могут использовать МН.
AVK>> Не путай пожалуйста IL-код и-managed код.
VD>Не путаю. IL == managed.
Ничего подобного. Цитата из MSDN
Compilers and tools expose the runtime's functionality and enable you to write code that benefits from this managed execution environment. Code that you develop with a language compiler that targets the runtime is called managed code; it benefits from features such as cross-language integration, cross-language exception handling, enhanced security, versioning and deployment support, a simplified model for component interaction, and debugging and profiling services.
Слабо сделать класс с МН, чтобы его можно было использовать из C# или VB.NET?
VD> То о чем говоришь ты называется "CLS-совместимый".
Нет, CLS совместимый это отвечающий стандарту CLI. Вот к примеру uint вполне себе менеджед, но не CLS-compliant. Комплиантность к CLS обозначается атрибутом CLSCompliant.
Здравствуйте, VladD2, Вы писали:
AVK>>Да начерта их эмулировать? Это самоцель что ли?
VD>Дык удобнее с ними.
Но это не значит что аналогичный по назначению , но реализованный иначе механизм существовать не может.
VD> Ты сам попробуй на Шарпе пописать без делегатов...
А там им замены нет.
AVK>> Делегаты — неплохое приближение к идеалу, но совершенно точно еще не идеал. С введением к примеру анонимных методов станет все еще интереснее.
VD>Я кстати, так и не просек в чет тут кайф.
Здравствуйте, VladD2, Вы писали:
_>>Этот код нетипобезопасен — если написать C2: public C1<C3> или вызвать C1::Method1 из конструктора C1, то возникнет неопределенное поведение. VD>Ну, C3 бесспорно. Можно правда обезопаситься делая не статик-каст, а динамик-, но это уже медленнее. А насчет вызова метода из коструктора ты ошибаешся. Тут все будет ОК.
Твой десятилетний опыт работы с плюсами должен был подсказать тебе, где ошибка
Вот пример, вызывающий access violation. Убери вызов Method1 из конструктора C1 — access violation пропадет.
#include <iostream>
#include <string>
using namespace std;
template<class Base>
class C1
{
public:
C1()
{
Method1(); // !
}
void Method1()
{
Base * pBase = static_cast<Base*>(this);
pBase->SomeUniversalWork();
}
};
class C2: public C1<C2>
{
public:
string s;
void SomeUniversalWork()
{
cout << s << endl;
}
};
int main()
{
C2 c2;
c2.Method1();
}
_>>class C2 : C1<C2>, ISomeUniversalWork _>>{ _>> int ISomeUniversalWork.SomeUniversalWork() { _>> return 0; _>> }
VD>Не. Не прокатит. Если отнаследовался от интерфейса, то обязан реализовать метод.
А int ISomeUniversalWork.SomeUniversalWork() — это что?
VD>На счет тормозов. Да такое приведение будет динамик-кастом и скорость будет ниже. Но ведь можно делать приведение один раз и запоминать указатель в скрытом поле. При этом будет производиться или thiscall, или инлайнинг.
Внутри C1 мы можем сохранить указатель только на ISomeUniversalWork, и при вызове по нему инлайнинга точно не будет. В моем примере в принципе может быть, но для этого джит должен:
1) раскрыть инлайном C1::Method1;
2) понять, что после раскрытия this на самом деле является C2, потому что Method1 вызван для объекта типа C2;
3) в связи с этим убрать приведение this к C2 как лишнее;
4) понять, что метод C2::ISomeUniversalWork.SomeUniversalWork невиртуальный и его можно инлайнить;
Пункт 2 наименее вероятен, но без него ничего не выйдет.
Здравствуйте, VladD2, Вы писали:
_>>class C1<T> where T : ISomeUniversalWork { _>> public void Method1() { _>> int i = ((T)this).SomeUniversalWork(); _>> } _>>}
VD>Но ведь можно делать приведение один раз и запоминать указатель в скрытом поле.
А, действительно и в поле типа T можем. Получается почти как в ATL, но там они еще экономили место под указатель. Совсем как в ATL может быть только с приведением прямо в месте вызова, но компилятор должен быть слишком умным, как я описал.
Здравствуйте, WolfHound, Вы писали:
WH>Здравствуйте, VladD2, Вы писали:
VD>>А кто это говорил? Тебе говорят, что он тяжел и во многом отстал от жизни. Цитату можешь привести? WH>Re[9]: Будущее C#
Ну, ты прочти в каком контексет там употреблено это слово, и в будущем не выдирай слова из контекста. С точки зрения знания о рантайме С++ действительно приметивен. Но это конечно же не означает, приметивности его как языка.
... << RSDN@Home 1.1 beta 1 >>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, VladD2, Вы писали:
VD>Я тебя не удевлю если скажу, что все это можно сделать и на Шарпе (т.е. без шаблонов)? Причем решения будут даже более красивыми.
Затыкание дырок C#? Забавно.
VD>Так что твои примеры скорее являются доказательством высказанной мною мысли, о том что 90% использования шаблонов в С++ является затыканием дырок языка. И вызваны прощетами в языке.
Эдак любую библиотеку можно назвать затыканием дырок языка, на котором она написана.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
[...]
VD>Дык информация о типах нужна то обычно в рантайме, а вот тут у плюсов идеологический калапс. Его авторы просто не думали о рантайме при проектировании языка.
Они сознательно ограничивали его рассмотрение. И ИМХО, совершенно разумно, поскольку необходимость "самоанализа" (он же — rtti) в сущности, является ошибкой дизайна.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Они сознательно ограничивали его рассмотрение. И ИМХО, совершенно разумно, поскольку необходимость "самоанализа" (он же — rtti) в сущности, является ошибкой дизайна.
Если ошибочный дизайн приводит к более простому и ясному коду, чем правильный, то пора пересмотреть методы оценки дизайна.