Здравствуйте, criosray, Вы писали:
ГВ>>CouchDB не на Эрланге разве? Это ж не совсем то, что мы понимаем под managed. C>Это Ваши проблемы, что Вы не понимаете что такое managed. Ерланг — самый настоящий управляемый язык.
Ладно, пусть так, чтобы не вдаваться в смысловые оттенки.
Я знаю только две бесконечные вещи — Вселенную и человеческую глупость, и я не совсем уверен насчёт Вселенной. (c) А. Эйнштейн
P.S.: Винодельческие провинции — это есть рулез!
E>>>>Ой-ой-ой, какие мы умные. Как проектирование UI относится вообще к языку реализации? ЭТО НЕСВЯЗАННЫЕ ВОПРОСЫ!!! C>>>При чем тут язык? Мы как бы обсуждаем два конкретных продукта: gimp и paint.net Не заметили?
E>>Правда? А почему она, тогда, называется "За что я не люблю С++"?
C>Память коротка? Тему на фотики перевели Вы.
А так что скажешь?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, criosray, Вы писали:
C>Ну а почти весь middle- и front-end пишутся на управляемых языках: джава и дотнет в первую очередь.
Ну так там и производительность обычно некритична...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, Qbit86, Вы писали:
Q>Что-то я запутался, в этой ветке я за дотнет вразумляю, или за сиплюсплюс?
Ну, раз я внесён-таки уже "в реестр недостойных внимания", то день знаний уже не наступит.
MX>>Инкремент/декремент не может быть лишним. MX>>Я не знаю, зачем вы это повторяете. Я никогда boost::shared_ptr по ссылке не передаю. А Вы?
Q>Я же выше намекнул, что проверить можно через use_count(), почему ты этого не сделал? Я должен за тебя код набирать? Хорошо, в последний раз я это сделаю.
Q>
Другими словами, Вы часто передаёте shared_ptr по ссылке (а внутри не создаёте копию прежде, чем делать что-либо ещё) и нет, по Вашему мнению, с этим никаких проблем, одна только экономия? Тогда Вы ошибаетесь, вот смотрите:
boost::shared_ptr<int> g;
void Bar(boost::shared_ptr<int> const & o)
{
g.reset(); // не обязательно прямо так, это м.б. и вызов какой-нибудь функции, которая из какого-нибудь list-а удаляет shared_ptr
*o = 42;
}
Всё замечательно, пока мы не делаем Bar(g). По-этому НИКОГДА нельзя передавать shared_ptr по ссылке (м.б., разве что, в конструктор, чтобы тут же его скопировать в поле класса, но и это не всегда надёжно по той же причине).
MX>>Инкремент/декремент не может быть лишним. Я не знаю, зачем вы это повторяете.
Q>Я не знаю, зачем ты упорно отрицаешь вещи, очевидные любому C++-программисту. Алсо, почитай книжки, где рассказывается про 1) ссылки/уазатели, 2) влавдение/аггрегацию/композицию, etc.
Мне книжки уже не помогут, дурака учить — только портить.
MX>>И где экономия?
Q>Я уже отчаялся тебе хоть что-то объяснить. Впредь я не буду даже пытаться.
Спрашивая про экономию, я приводил ещё и код, который ОБЯЗАТЕЛЕН в данном случае.
MX>>_Просто_ "ссылаются два человека" и ни один не владеет? ЗдОрово!
А почему Вы цитируете мои слова, которые относятся к С#, не полностью, отрывая самое важное, а потом ещё и перепрыгиваете на С++? А я, между прочим, спрашивал "Ну-ка, покажите мне — как уничтожить, в таком случае, почку по полной программе (и я опять не имею в виду Dispose, потому, что он — не уничтожение)?"
Q>Ты ничего не понимаешь в понятиях «ссылается» и «владеет». Точка, абзац. Вот тебе пример на C++ (потому что C#, очевидно, для тебя слишком сложен тем, что значок «=» означает в нём копирование ссылки): Q>
Q>Здесь есть 3 идентификатора — p, ref1, ref2. Чем-то владеет только p. Остальные — это ссылки на него, объявление ссылки не приводит к разделению владения. Не веришь — проверь: Q>
Как на С# записать аналог "ref1.reset()", в моём примере про почку и 2-х человек, Вы так и не ответили. И, если такого кода нет, стало быть Вы не правы, утверждая, что
Здесь нет ни передачи владения, ни его разделения. Здесь на одну почку ссылаются два человека. Если любой из них умрёт и вызовет Dispose() для себя и подобъектов, то у другого будет невалидная почка.
Соответственно и тут:
значок «=» означает в нём (в C#, прим. моё) копирование ссылки
Вы не правы, т.е. невозможно уничтожить насовсем объект, пока на него есть хоть одна ссылка, а вызов какого-то там Dispose ничего не говорит о владении. Эдак можно сказать, что и файл не расшарен между p1 и p2 тут:
Т.к. всегда можно сделать "p1->close()".
MX>>Короче, нет никакого способа в C# передать поле (вообще объект) в метод, не передав владения. Так и запишем.
Q>Ага, так и запиши. Повторяй, как мантру. Совершенно очевидно, что ты не заинтересован в «понять», а заинтересован в «переспорить». Вообще-то, встречая явно провокационные (читай «толстый троллинг») фразы типа «В общем, картина начинает проясняться»
, полезно заблаговременно вносить собеседника в реестр недостойных внимания и не тратить на них более времени.
Я про "запишем" — исключительно для того, чтоб Вы меня не забыли опровергнуть и правильно процитировали. А Вы не сделали ни того, ни другого. Я-б теперь мог бы и извиниться, но не из "реестра недостойных".
А где не было про "запишем", Вы меня повырезали вовсе.
Короче, я остался при своём:
* в C# есть только передача владения (предположу, что есть исключение — встроенные типы, чтоб было не без аномалий)
* shared_ptr — только по значению, без вариантов
* подсчёт ссылок в C# только так (2 места, где можно ошибиться — забыть Clone или Using):
void foo(RefCounter<HugeBitmap> h)
{
using (h)
{
}
}
foo(hugeBitmap.Clone());
сравните с С++ (ошибаться негде — передачу по ссылке видно невооруженным глазом):
MX>Другими словами, Вы часто передаёте shared_ptr по ссылке (а внутри не создаёте копию прежде, чем делать что-либо ещё) и нет, по Вашему мнению, с этим никаких проблем, одна только экономия? Тогда Вы ошибаетесь, вот смотрите: MX>
MX>boost::shared_ptr<int> g;
MX>void Bar(boost::shared_ptr<int> const & o)
MX>{
MX> g.reset(); // не обязательно прямо так, это м.б. и вызов какой-нибудь функции, которая из какого-нибудь list-а удаляет shared_ptr
MX> *o = 42;
MX>}
MX>
MX>Всё замечательно, пока мы не делаем Bar(g). По-этому НИКОГДА нельзя передавать shared_ptr по ссылке (м.б., разве что, в конструктор, чтобы тут же его скопировать в поле класса, но и это не всегда надёжно по той же причине).
Z в целом с тобой согласен, но вот тут конкретно не совсем. Всё-таки большинство функций стараются писать так, чтобы сторонних эффектов не было... Так что подобная предосторожность в типичной функции -- лишняя...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Здравствуйте, -MyXa-, Вы писали:
MX>* в C# есть только передача владения (предположу, что есть исключение — встроенные типы, чтоб было не без аномалий)
Понятие "передача владения" Вы сами придумали. Есть value-типы, есть ref-типы. Пока на объект реф типа есть "живые" и не слабые (WeakReference) ссылки GC его уничтожать не станет. Для детерменированного освобождения ресурсов применяется патерн IDisposable, позволяющий явно вызвать метод "закрытия" хэндла (неуправляемого ресурса) в детерменированный момент времени.
MX>* shared_ptr — только по значению, без вариантов MX>* подсчёт ссылок в C# только так (2 места, где можно ошибиться — забыть Clone или Using): MX>[c#] MX>void foo(RefCounter<HugeBitmap> h) MX>{ MX> using (h) MX> { MX> } MX>}
Это бессмыслица. Работать либо не будет совсем, либо будет идентично
using (var h = new HugeBitmap) {} но с лишним слоем абстракции.
Не пытайтесь применять приемы, работающие в неуправляемых средах, к управляемым. Особенно, если не понимаете принципов работы сборщика мусора и патерна Disposable.
Здравствуйте, criosray, Вы писали:
C>Понятие "передача владения" Вы сами придумали. Есть value-типы, есть ref-типы. Пока на объект реф типа есть "живые" и не слабые (WeakReference) ссылки GC его уничтожать не станет. Для детерменированного освобождения ресурсов применяется патерн IDisposable, позволяющий явно вызвать метод "закрытия" хэндла (неуправляемого ресурса) в детерменированный момент времени.
Ты не прав, criosray. «Передача владения» и «разделение владения» известные термины. Позже, быть может, я подробнее прокомментирую.
MX>>[Skipped.] C>Это бессмыслица.
Да, это бессмыслица.
C>Не пытайтесь применять приемы, работающие в неуправляемых средах, к управляемым.
Здравствуйте, -MyXa-, Вы писали:
Q>>Вообще-то, встречая явно провокационные (читай «толстый троллинг») фразы типа «В общем, картина начинает проясняться» и «Так и запишем», полезно заблаговременно вносить собеседника в реестр недостойных внимания и не тратить на них более времени. MX>Я про "запишем" — исключительно для того, чтоб Вы меня не забыли опровергнуть и правильно процитировали.
Я прошу прощения, если обидел тебя незаслуженно.
MX>Другими словами, Вы часто передаёте shared_ptr по ссылке...
Не то чтобы часто, потому что благополучно мигрировал на .NET (чего и всем желаю). Но когда писал на C++ — да, передавал по ссылке на константу.
MX>а внутри не создаёте копию прежде, чем делать что-либо ещё
Это зависит от того, «моя» ли это функция. Если бы это была моя функция, то при необходимости я делал бы копию внутри (или сразу принимал по значению, depends on). Если бы это была не моя функция, и при этом 1) она принимала аргумент по ссылке, 2) в документации говорилось, что у неё есть (извратные) побочные действия, то я бы делал копию снаружи.
MX>и нет, по Вашему мнению, с этим никаких проблем, одна только экономия?
Здесь проблема не «с этим», а с логикой. (Подробности будут ниже.)
MX>Тогда Вы ошибаетесь...
Я отлично знаю разницу между передачей по значению и по ссылке.
MX>вот смотрите:
MX>boost::shared_ptr<int> g;
MX>void Bar(boost::shared_ptr<int> const & o)
MX>{
MX> g.reset(); // не обязательно прямо так, это м.б. и вызов какой-нибудь функции, которая из какого-нибудь list-а удаляет shared_ptr
MX> *o = 42;
MX>}
Корни той проблемы, что ты описал, не имеют отношения к подсчёту ссылок вообще и к boost::shared_ptr в частности. [offtopic]Кстати, C# хорош тем, что упрощает использование идиомы иммутабельности, которая, в свою очередь, уменьшает количество разделяемых изменяемых состояний. Соответственно уменьшает зависимости от data flow и control flow (что помимо прочего улучшает распараллеливаемость). С переходом на C# я почти забыл про ошибки такого рода.[/offtopic]
MX>Всё замечательно, пока мы не делаем Bar(g). По-этому НИКОГДА нельзя передавать shared_ptr по ссылке.
О противного. Последовательно следуя твоей логике получим, что «НИКОГДА» нельзя передавать любые объекты по ссылке — в виду следующего аналогичного кода:
class VeryLargeObject
{
private:
int value_;
bool valid_;
public:
explicit VeryLargeObject(int value) : value_(value), valid_(true) { }
~VeryLargeObject() { valid_ = false; }
int GetValue() const
{
if (!valid_)
throw std::runtime_error("Trying to get member of destroyed object.");
return value_;
}
};
std::vector<VeryLargeObject> g;
void Foo(VeryLargeObject o)
{
g.clear();
o.GetValue();
}
void Bar(VeryLargeObject const& o)
{
g.clear();
o.GetValue();
}
int main ()
try
{
g.push_back(VeryLargeObject(42));
Foo(g[0]); // OK.
Bar(g[0]); // UB в теории, и (возможно) наш runtime_error на практике.
}
catch (std::exception const& ex)
{
std::cout << ex.what() << std::endl;
}
MX>Мне книжки уже не помогут, дурака учить — только портить.
И всё-таки советую.
MX>А почему Вы цитируете мои слова, которые относятся к С#, не полностью, отрывая самое важное, а потом ещё и перепрыгиваете на С++?
Перепрыгиваю на C++, чтобы отделить те ньюансы, которые свойственны исключительно C#, от тех ньюансов, которые справедливы вообще.
MX>А я, между прочим, спрашивал "Ну-ка, покажите мне — как уничтожить, в таком случае, почку по полной программе (и я опять не имею в виду Dispose...
Это всё равно, что спрашивать «как уничтожить почку на C++, удалив из исходника shared_ptr'а деструктор».
MX>не имею в виду Dispose, потому, что он — не уничтожение
Я настаиваю, что Dispose — уничтожение. Это логическое уничтожение, типа свойству Valid почки присвоить false (аналог освобождения неуправляемого ресурса). Физическое удаление сборщиком — это просто возвращение памяти менеджеру управляемой кучи, никаких дополнительных действий типа вызова финализатора выполняться не будет (если правильно реализовать паттерн Disposable).
MX>Как на С# записать аналог "ref1.reset()", в моём примере про почку и 2-х человек, Вы так и не ответили.
a.Dispose() (или что там было, я не помню уже).
MX>Вы не правы, т.е. невозможно уничтожить насовсем объект, пока на него есть хоть одна ссылка
Наличие ссылки ровным счётом ничего не говорит кроме того, что память под объект пока не возвращена менеджеру. Объект может быть уничтожен логически (отпущены все ресурсы (битмапы, кисти, стримы, etc.), обнулены ссылки на них, на объект повешена табличка «невалиден»), а физически просто болтается немного памяти под экземпляр. Если у тебя есть ссылка на эту область, эта память не будет освобождена, ты по-прежнему можешь обращаться к ней. Результат такого обращения всецело зависит от разработчика класса, что он предусмотрел в вызове свойств логически уничтоженного объекта.
MX>а вызов какого-то там Dispose ничего не говорит о владении.
При правильной реализации паттерна Disposable, Dispose() убивает те объекты, какими владеет этот класс. Например, вызывает для них Dispos'ы, ссылкам на dispos'нутые части присваивает null, etc.
MX>Короче, нет никакого способа в C# передать поле (вообще объект) в метод, не передав владения.
Ещё раз, мы просто передаём ссылку: «void Foo(RefCounter<Bitmap> h)». Если разработчикам функции вдруг понадобилась глубокая копия, они всегда могут сделать Copy()/Dispose() внутри:
Но делать так, как ты сказал — снаружи Copy(), внутри Dispose() — нонсенс.
MX>* в C# есть только передача владения (предположу, что есть исключение — встроенные типы, чтоб было не без аномалий)
Это не так.
MX>* shared_ptr — только по значению, без вариантов
Ты согласен, что если в твоих обоснованиях этого утверждения заменить boost::shared_ptr<int> на std::vector<VeryLargeObject>, то с помощью тех же рассуждений можно прийти к заведомо абсурдному выводу «большие объекты — только по значению, без вариантов»?
MX>* подсчёт ссылок в C# только так (2 места, где можно ошибиться — забыть Clone или Using): MX>
Не так, а чтобы Copy() и Dispose() были на одном уровне:
// 1) Просто используем h, если разработчику функции не нужна особая логика.void Foo(RefCounter<HugeBitmap> h)
{
...
}
// 1) В случае, если разработчику функции нужна особая логика.void Foo(RefCounter<HugeBitmap> h)
{
using (var temp = h.Copy())
{
...
}
}
...
// A) Если пользователю не нужна особая логика.
Foo(hugeBitmap);
// B) Если пользователю нужна дополительная логика.using (var temp = hugeBitmap.Copy())
{
...
Foo(temp);
...
}
Здравствуйте, hattab, Вы писали:
H>Здравствуйте, Erop, Вы писали:
H>>>Paint.NET использовал преимущества двуядерного проца. Это три.
E>>Кстати, то, что многие проги повадились незапрящаемым образом загружать все возможные нити не несколько напрягает.
H>Я с Paint.NET'ом это удовольствие огреб в полной мере, со своим-то одноядерником Запускаю генерирование фрактала Мандельброт. Paint.NET открывает диалог с настройками этой отрисовки, а сам в фоне начинает считать и рисовать с текущими настройками (правда у меня есть сомнения, что настройки дефолтные, а не оставшиеся от предыдущих экспериментов). Что я имею? Я имею 100% загрузку проца и неотвечающие контролы. В общем, Paint.NET моей бутявке противопоказан
Да вааще что творят, а?!! Придумали тут многопоточность и многоядерность, ща вот еще GPGPU подятнеться. Это что ж твоя бутявка то делать будет? В топку их всех, в топку!!!
E>>У меня часто так бывает, что идёт какой-то долгий процесс и я в это время в чём-то ещё ковыряюсь. Так вот Я БЫ ХОТЕЛ, ЧТОБЫ ЭТО "ЧТО_ТО ЕЩЁ" НЕ ТОРМОЗИЛО МОЙ ДОЛГИЙ ПРОЦЕССС!!!
H>Решение есть Ставишь Prio (это экстендер к таск-менеджеру) (ссылки нет у меня ) и выставляешь тяжелому процессу самый низкий приоритет (Prio эти настройки сохраняет поэтому сделать это нужно только один раз). Я так видео иногда перекодирую, сразу в 4-5 VirtualDub'ах (про очередь знаю, если что ).
Ага, точно, и вообще, для графики и редактирования видео многопоточность категорически противопоказана (а особенно в 4-5 VirtualDub'ах)!!!
Luck in life always exists in the form of an abstract class that cannot be instantiated directly and needs to be inherited by hard work and dedication.
Здравствуйте, yuriylsh, Вы писали:
H>>Я с Paint.NET'ом это удовольствие огреб в полной мере, со своим-то одноядерником Запускаю генерирование фрактала Мандельброт. Paint.NET открывает диалог с настройками этой отрисовки, а сам в фоне начинает считать и рисовать с текущими настройками (правда у меня есть сомнения, что настройки дефолтные, а не оставшиеся от предыдущих экспериментов). Что я имею? Я имею 100% загрузку проца и неотвечающие контролы. В общем, Paint.NET моей бутявке противопоказан
Y>Да вааще что творят, а?!! Придумали тут многопоточность и многоядерность, ща вот еще GPGPU подятнеться. Это что ж твоя бутявка то делать будет? В топку их всех, в топку!!!
В нормальном десктопном софте, фоновым тредам принято устанавливать низкий приоритет, чтоб они не оказывали влияние на тред работающий с гуем. Видимо кто-то это не осилил в университетах
E>>>У меня часто так бывает, что идёт какой-то долгий процесс и я в это время в чём-то ещё ковыряюсь. Так вот Я БЫ ХОТЕЛ, ЧТОБЫ ЭТО "ЧТО_ТО ЕЩЁ" НЕ ТОРМОЗИЛО МОЙ ДОЛГИЙ ПРОЦЕССС!!!
H>>Решение есть Ставишь Prio (это экстендер к таск-менеджеру) (ссылки нет у меня ) и выставляешь тяжелому процессу самый низкий приоритет (Prio эти настройки сохраняет поэтому сделать это нужно только один раз). Я так видео иногда перекодирую, сразу в 4-5 VirtualDub'ах (про очередь знаю, если что ).
Y>Ага, точно, и вообще, для графики и редактирования видео многопоточность категорически противопоказана (а особенно в 4-5 VirtualDub'ах)!!! Y>
VirtualDub таки распараллеливается, чего ты так возбудился? А 4-5 инстансов использую т.к. он (VirtualDub), не то из-за кодеков, не то из-за ошибок во входящем потоке, иногда таки падает, и если использовать его очередь, то очередь он унесет вместе с собой. А так, один из 4-5 упал ночью, так и не страшно -- другие-то проболжают работать.
Здравствуйте, hattab, Вы писали:
Y>>Ага, точно, и вообще, для графики и редактирования видео многопоточность категорически противопоказана (а особенно в 4-5 VirtualDub'ах)!!! Y>>
H>VirtualDub таки распараллеливается, чего ты так возбудился? А 4-5 инстансов использую т.к. он (VirtualDub), не то из-за кодеков, не то из-за ошибок во входящем потоке, иногда таки падает, и если использовать его очередь, то очередь он унесет вместе с собой. А так, один из 4-5 упал ночью, так и не страшно -- другие-то проболжают работать.
Не знаю где ты там углядел чье-либо возбуждение, не хочу даже думать об этом. А если ты о количестве смайликов и восклицательных знаков, то это если ты не понял, просто в тон к твоим с Еrоp сообщениям.
То что VirtualDub распараллеливается я то как раз прекрасно понимаю, я думаю, иронию в моих словах сложно было не уловить. Обрати внимание на категорию приложений указанных мной (хинт, чтобы избежать повторного недопонимания и грез о возбужденных от твоих слов собеседников — графика и видео как раз те области, которым многопоточность — то что доктор прописал). Просто ты похаял одно приложение за использование многопоточности, ибо твоей одноядерной "бутявке" сложно это переварить и тут же приводишь другое, использующее многопоточность во весь рост да еще и в 4-5 экземплярах одновременно. Так держать!
Luck in life always exists in the form of an abstract class that cannot be instantiated directly and needs to be inherited by hard work and dedication.
Здравствуйте, yuriylsh, Вы писали:
Y>>>Ага, точно, и вообще, для графики и редактирования видео многопоточность категорически противопоказана (а особенно в 4-5 VirtualDub'ах)!!! Y>>>
H>>VirtualDub таки распараллеливается, чего ты так возбудился? А 4-5 инстансов использую т.к. он (VirtualDub), не то из-за кодеков, не то из-за ошибок во входящем потоке, иногда таки падает, и если использовать его очередь, то очередь он унесет вместе с собой. А так, один из 4-5 упал ночью, так и не страшно -- другие-то проболжают работать.
Y>Не знаю где ты там углядел чье-либо возбуждение, не хочу даже думать об этом. А если ты о количестве смайликов и восклицательных знаков, то это если ты не понял, просто в тон к твоим с Еrоp сообщениям.
А где в моем сообщении куча смайлов и восклицательных знаков? Между строк читаешь?
Y>То что VirtualDub распараллеливается я то как раз прекрасно понимаю, я думаю, иронию в моих словах сложно было не уловить. Обрати внимание на категорию приложений указанных мной (хинт, чтобы избежать повторного недопонимания и грез о возбужденных от твоих слов собеседников — графика и видео как раз те области, которым многопоточность — то что доктор прописал). Просто ты похаял одно приложение за использование многопоточности, ибо твоей одноядерной "бутявке" сложно это переварить и тут же приводишь другое, использующее многопоточность во весь рост да еще и в 4-5 экземплярах одновременно. Так держать!
Я, как ты изволил выразиться, похаял приложение не за использование, а за способ приготовления. Разницу улавливаешь? А VirtualDub позволяет таки устанавливать у молотящих тредов любой приоритет, потому и не мешает, ни работе своего гуя, ни работе окружающих приложений.
Здравствуйте, Геннадий Васильев, Вы писали:
ГВ>Ну как же, ничего военного?! Зато ты теперь не сможешь с лёгкостью неимоверной приклеить одну и ту же функцию к свойствам, переменным и вообще к классам, реализующим семантику присвоения значения.
За неимением классов, реализующих семантику присвоения значения, приклеить к ним ничего не удастся. Увы. ГВ>Я уж не говорю об эстетике: ГВ>
ГВ>var bOk = new StoredProperty<bool>(false);
ГВ>var bCancel = new StoredProperty<bool>(true);
ГВ>
ГВ>Это ж кошмар какой-то: алгебраические типы (!), new (!!), рефлексия (!!!),
Здесь нет никакой рефлексии. Рефлексия предусмотрена для другого случая. ГВ>Извини, я не удержался.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, criosray, Вы писали:
c> c>> M>Кстати, ни Гимп ни Paint.net не поддерживают нормально работу с RAW — а вот это уже плохо
c> c>> Возможно. Опять же это уже скорее профессиональный уровень.
c> M>Далеко не профессиональный
c> А что тогда профессиональный уровень? А какой процент пользователей вообще знает, что такое "работа с RAW"?
c> Мамут, ей богу, Вы как ребенок...
Я лучше послушаю определение любительского уровня.
ЛЮБИ'ТЕЛЬ, я, м.
1. чего и с инф. Имеющий склонность или пристрастие к чему-н. Л. музыки. Л. шахматной игры. Л. покушать. Страстный л. лошадей. 2. без доп. Занимающийся чем-н., как дилетант; противоп. профессионал. Труппа любителей. Шахматный турнир любителей
ПРОФЕССИОНА'Л, а, м.
Человек, сделавший какое-н. занятие своей постоянной профессией.
Здравствуйте, criosray, Вы писали:
c> c>>> M>Кстати, ни Гимп ни Paint.net не поддерживают нормально работу с RAW — а вот это уже плохо
c> c>>> Возможно. Опять же это уже скорее профессиональный уровень.
c> M>>Далеко не профессиональный
c> H>Кстати, к GIMP'у есть расширение для работы с RAW.
c> http://www.softpedia.com/get/Multimedia/Graphic/Graphic-Plugins/RawLoader.shtml
Здравствуйте, dmitry_npi, Вы писали:
_>Да нет, я-то сам его люблю. Случайно наткнулся на статью здесь. _>Он не просто его, не любит, он его ненавидит. И других заразить пытается. _>Вот, думаю, тролль Отличная приманка для священной войны.
Очень интересная статейка, сколько я таких быдланов повидал и пообламывал, хотелось бы пройтись по вышеозначенному документу, сравнивать плюсы буду с жабой, те там где имею опыт (а не так как делают шарписты обсирая язык который знают по наслышке):
1.
Впервые с зыком С++ я столкнулся почти 15 лет назад (почуствуйте какой стаж начав работать на Turbo C++. Тогда из доступной литературы по объектно-ориентированному программированию у меня было очень хорошее (как мне тогда казалсь) руководство по ООП на Turbo Pascal 5.5.
[0xC0000005]
Ха, вот имено столкнулся, лбами, и судя по всему скорлупа его мозга дала непоправимую трещину, сорри за лирику — не выдержал.
А по сути человек сам говорил что столкнулся впервые 15 лет назад, я тоже 15 лет назад столкнулся с бейсиком, но я считаю я не могу осуждать тот язык управляющий "Электроникой БК-10" за то что у меня что-то не получилось, что-то сломалось, и на экзамене я затёр учительскую дискету.
У него было руководство по ООП — книга по паскалю. Занятно, как такой гений (как о нём тут шарписты шаркают) выбрал имено Паскаль 5.5, ведь в нём небыло обьектов, если помните Pascal with Objects был введён с версии 7.0 борландовсой ИДЕ, и у меня в школе была эта замечательная книга, в которой строилась симуляция шахматной доски, и для Паскаля она была замечательной, но не для ООП, нет и ещё раз нет, ООП это не база для языка, ООП это методика организации логики которая может поддерживаться языком. Это как говорить о том, что я выучил курс гидромеханики разобрав медицинксий шприц или клизму — вы поймёте одно два правила, но не поймёте науки.
2.
Со временем пришло понимание, что на С++ иначе просто нельзя !!! Средства, изначально заложенные в сам язык, настолько негибки и жестки, что реализовывать системы, требующие гибкости на С++ было крайне тяжело и постояннно приводило к кривым способам (т.е. это бага а фича .
И вот такого там 90%, изречения ничем не обоснованные, замете, что автор говорит сугубо о своём опыте, о неудачном опыте, он не говорит о том что этими корявыми средствами он делал шедевры, а говорит что в его кучерявом дизайне и коде виноват имено С++, это называется трезумция виновности, когда отталкиваются от обвинения, а не от защиты.
А примеры? Как такой крутой перец и гуру не наваял нам с десяток красивых примеров.
И вот тут я хочу остановиться на книге "Exceptional C++" в двух томах, где описывается как молодой девелопер может сделать криво, а как после прочтения это можно сделать шедеврально.
3.
Только вот как понимать ОО — я не думаю, что программисты, пишущие на Smalltalk'е, сочтут С++ объектно- ориентированным языком. Даже по сравнению с Java С++ явно в проигрыше — нет интерфейсов (зато есть множественное наследование со всеми его проблемами), объектная модель просто отсутствует.
Только вот как понимать ОО — это дядя Гуголь поможет, и лучше всех это опишет простая тётя Вика, которая скажет вам что ООП — парадигма программирования, в которой основными концепциями являются понятия объектов и классов. Вот она в чём парадигма, её база, и если копнуть глубже то основные её компоненты поддерживаются в С++.
Даже по сравнению с Java С++ явно в проигрыше
Вот это да, 4 года работаю с жабой в "огромных" (компания лидер в индустрии, не буду называть) индустриальных масштабах, и всегда видел интерфейс как "заплатку" на дырень моно-наследования. А дело было вот как, и это можно увидеть по эволюции, разработчики Явы сказали — нам не нужно множественное наследование, потому-что есть такие кучеряшки, которые могут при помощи паяльной лампы картошку варить, но при этом дерево иерархий превращялось в список, что делало из полиморфизма обрубок. Тогда решили сделать множественное наследование, и разрешить наследовать от одного класса, и одного и более недо-класса, который не мог бы вызвать испражнения из кучерявых пальцев говнокодеров, те никаких имплементаций, которые могут вызвать двоиственность сущностей, только описание метода, или словами микрософта — Pure Virtual Function.
Много ли Вы знаете простых и удобных persistence-библиотек для С++, которые бы сами могли сериализовать произвольные объекты ? Максимум, что есть, это сложные библиотек с кучей ограничений и необходимостью вручную (зачастую при помощи макросов) задавать фактически часть метаинформации.
Во первых зачем? А во вторых эти сахарные названия Persistence, Hibernate, DataObject, Serializable... как это всё напоминает ныне покойный билдер с его ВСПЛ(только не надо о его реинкорнации в кодгеар), и замете билдер был и под плюсы, и всё там было, но оказалось ненужным в настоящем языке, а всё потому-что плохому танцору... нужны контролы, компоненты, фичи, крутой язык, автоматика во всём, даже мозх автоматический, 500 крутых названий, зазубривши которые ты зовёшся гуру.
А много ли явошарпы знают удобных, простых и "интуитивно" понятных способов расширить функционал языка? Вот у меня требование к либе, я хочу регить callbackи вот таким способом:
alarmNotifier = GUIHandler::onAlarm + CoreRoutine::onAlarm
и что? у вас есть "костыль"? или всё чего нету нам не надо? Ха, это мертвецки неправильно, и обычно такое отмирает как несовершенное.
А как просто вам при вызове логгера указать текущее имя файла, исходника я имею ввиду,ай как вы ругали макросы, это так, это сяк, а как вы напишете:
logger::log(__filename__, __line__, "log text")
Ой, а никак, и даже костыли такие не выпускают, фабрика ещё не открылась, ну ничё, когда дядя Билл захочет нам это надо будет
А вот в Smalltalk'е или в Python'е таких библиотек полно.
Ага, а теперь скажите мне, у меня огромный обьект, но я хочу сериализовать только, замете слово ТОЛЬКО хидеры во всей иерархий, вот так я это использовал:
dataStream << Modifiers::HeadersOnly << hugeObject;
Слабо? или вы можете кичиться только готовыми фичами, но поверте мне, до 50% времени у больших команий использующих управляемые языки уходит на обход невозможности что-то сделать самому. И давайте честно, с примерами — сделайте мне на Яве универсальный алгоритм, да, который берёт генерик класс и делает с ним что-то своё, что есть общее для генерика. И не говорите мне что этот обрубок шаблонного метода вообще можно считать генерик, напишите-ка
public <T> void f()
{
T t = new T();
t.f();
}
Аааа, какой ужос, нельзя вызвать ничего из общего класса, ничего, есть только мега-костыли которые опустим здесь дабы не говнокодить.
Знаете что было придумано дабы обойти всё это? был сделан препроцессор для Явы, да, препроцессор, вернулись к яблони таки.
А как дела у С++ с интеграцией со скриптовыми языками
Вопрос должен стоять наоборот, а не почему все шурупы не поддерживают мою квадратную отвёртку.
Кроме того, С++ вообще не различает два существенно РАЗНЫХ понятия — абстрактнывй тип данных (АТД) и объект.
Те в С++ обьект и тип данных это одно и тоже? Не смешите мой зад.
А вот в Objective-C (другой вариант построения объектно-ориентированного языка на основе С, только в нем используется объектная модель языка Smalltalk) можно прямо на ходу узнать какие интерфейсы поддерживает объект, какие у него есть методы. Можно даже прямо на ходу добавить новый метод. И это компилируемый язык, весь графический интерфйес таких операционных систем как NeXTSTEP и Mac OS X построен именно на этом языке.
Хмм, всегда задавался вопросом о мозгах кодеров пишущих:
if(a instance of A1) ...
else if(a instance of A2) ...
else if(a instance of B) ...
else if(a instance of C) ...
Вот скажите мне серьёзно, хоть один реальный пример в рамках одного приложения(про распределённые системы отдельный разговор), когда на этапе компиляции тип обьекта не известен, а если он известен, то зачем его узнавать? Потеряли — плохой дизайн и кучерявые руки!!! + обрезанность языка.
С другной стороны, посмотрев на С++, становится понятно, почему делегирование замалчивалось. А как его можно реализовать на С++, как можно попросить какой-то объект вызвать какой-то метод (даже, если список входных параметров у него точно такой же) ?
А про шаблонные классы и алгоритмы автор видимо не читал, где вызов подставляется на этапе компиляции.
В С++ это практически невозможно сделать. Именно поэтому сперва в Delphi и C++ Builder, а затем и в остром С появилось возможность делегирования как расширение языка.
Именно поэтому два первых на сегодняшний день скончались а третий живёт только за счёт огромных вложений
void func1 ( A& a );
void func2 ( A a );
В чем разница между этими описаниями (кроме того, что возможно программист просто пропустил символ '&') ?
а в чём разница между func1(a) и func1(a.clone()), в том что в первом варианте кодер забыл вызвать клон
А как передать строку в Яве, чтобы она была output parameter? Вот смеху то, надо создавать холдеры, и почему в яве
void f(String s)
{
s = "I'm dummy";
}
переданный параметр не поменяется? и Вообще ни один параметр не поменяется? ах сколько говна было сьедено на этом миллионами программистами и тестерами. И вы говорите о том что управляемые языки там просты?
Есть примеры на STL, когда эффективность на простых строковых операциях падала в десятки раз.
А так же примеры где производительность увеличивалась в 1000 раз, и тоже благодаря аллокаторам из СТЛя, а сделайте ка мне аллокатор на шарпе дорогой (только не надо что менеджер памяти мега умный и всё знает, он ничего не знает кроме вашего говнокода)
Т.е. на С++ МОЖНО писать очень эффективно. И НЕКОТОРЫЕ даже пишут. Вопрос только — относитесь ли Вы к их числу ?
(бред г-на с хацкерским ником вырезан цензурой)
C>Вот это да, 4 года работаю с жабой в "огромных" (компания лидер в индустрии, не буду называть) индустриальных масштабах, и всегда видел интерфейс как "заплатку" на дырень моно-наследования. А дело было вот как, и это можно увидеть по эволюции, разработчики Явы сказали — нам не нужно множественное наследование, потому-что есть такие кучеряшки, которые могут при помощи паяльной лампы картошку варить, но при этом дерево иерархий превращялось в список, что делало из полиморфизма обрубок.
Дотнет и джава прекрасно обходятся без недоразумения под названием "множественное наследование". boost и stl по структуре и удобству смотряться очень и очень бедно на фоне .NET Framework.
Множественное наследование такой же моветон, как и goto.
(остальной бред г-на с хацкерским ником вырезан цензурой)
C>А много ли явошарпы знают удобных, простых и "интуитивно" понятных способов расширить функционал языка? Вот у меня требование к либе, я хочу регить callbackи вот таким способом: C>alarmNotifier = GUIHandler::onAlarm + CoreRoutine::onAlarm C>и что? у вас есть "костыль"? или всё чего нету нам не надо? Ха, это мертвецки неправильно, и обычно такое отмирает как несовершенное.
То, что есть у Вас еще бОльший костыль.
Что до расширяемых .NET языков — смотрите Nemerle и Boo.
C>А как просто вам при вызове логгера указать текущее имя файла, исходника я имею ввиду,ай как вы ругали макросы, это так, это сяк, а как вы напишете: C>logger::log(__filename__, __line__, "log text")
catch(Exception e) {
Log.Error(e); // через рефлексию будет собрана информация об исключении, потоке, методе, сборке, стеке вызовов(!!!)throw;
}
И Вы осмеливались утверждать, что Вы что-то знаете об управляемых языках? Да уж по части логеров управляемые языки рвут неуправляемые (в т.к. С++), как тузик — грелку. Вам только мечтать об удобстве отладки и логирования, предоставляемых средствами управляемых сред.
C>Ага, а теперь скажите мне, у меня огромный обьект, но я хочу сериализовать только, замете слово ТОЛЬКО хидеры во всей иерархий, вот так я это использовал: C>dataStream << Modifiers::HeadersOnly << hugeObject;
Сериализация в дотнет полностью управляется атрибутами. В С++ об этом опять же только мечтать.
[JsonObject(MemberSerialization.OptIn)]
public class LoginResult
{
private ResultErrors errors = new ResultErrors();
[JsonProperty("success")]
public bool Success { get; set; }
[JsonProperty("errors")]
public ResultErrors Errors
{
get { return errors; }
}
}
C>Слабо? или вы можете кичиться только готовыми фичами, но поверте мне, до 50% времени у больших команий использующих НЕуправляемые языки уходит на обход невозможности что-то сделать самому.
Исправил.
И давайте честно, с примерами — сделайте мне на Яве универсальный алгоритм, да, который берёт генерик класс и делает с ним что-то своё, что есть общее для генерика. И не говорите мне что этот обрубок шаблонного метода вообще можно считать генерик, напишите-ка
Вы сначала заставьте это компиллироваться под С++
C>public <T> void f() C>{ C> T t = new T(); C> t.f(); C>}
C>Аааа, какой ужос, нельзя вызвать ничего из общего класса, ничего, есть только мега-костыли которые опустим здесь дабы не говнокодить.
Что это за чушь?
C>Знаете что было придумано дабы обойти всё это? был сделан препроцессор для Явы, да, препроцессор, вернулись к яблони таки.
Какой еще препроцессор? Опишите задачу, чтоли. Посмотрим в чем у Вас ошибка дизайна.
C>Вот скажите мне серьёзно, хоть один реальный пример в рамках одного приложения(про распределённые системы отдельный разговор), когда на этапе компиляции тип обьекта не известен, а если он известен, то зачем его узнавать? Потеряли — плохой дизайн и кучерявые руки!!! + обрезанность языка.
COM
C>
C>void func1 ( A& a );
C>void func2 ( A a );
C>В чем разница между этими описаниями (кроме того, что возможно программист просто пропустил символ '&') ?
C>а в чём разница между func1(a) и func1(a.clone()), в том что в первом варианте кодер забыл вызвать клон C>А как передать строку в Яве, чтобы она была output parameter? Вот смеху то, надо создавать холдеры, и почему в яве
Ну давайте вспомним строки — самое больное место С++, чтоб забить последний гвоздь в гроб этого языка.
C>
C>void f(String s)
C>{
C> s = "I'm dummy";
C>}
C>
C>переданный параметр не поменяется? и Вообще ни один параметр не поменяется? ах сколько говна было сьедено на этом миллионами программистами и тестерами. И вы говорите о том что управляемые языки там просты?
Миллионами индусокодеров?
Опять же, в С# есть out параметры.
А уж если кидаться какашками, то давайте вспомним в С/С++ классическую ошибку:
if (a = 1) { ... }
об которую спотыкаются даже опытные программисты. Что заставляет многих применять костыль:
if (1 == a) { ... }
А уже про миллионы проблем, связанных с десятками реализаций строк и работы со строками в С++ на Вашем месте я б скромно умолчал.
Здравствуйте, criosray, Вы писали:
C>Множественное наследование такой же моветон, как и goto.
Какое смелое заявление.
C>>А как просто вам при вызове логгера указать текущее имя файла, исходника я имею ввиду,ай как вы ругали макросы, это так, это сяк, а как вы напишете: C>>logger::log(__filename__, __line__, "log text")
C>
C>catch(Exception e) {
C> Log.Error(e); // через рефлексию будет собрана информация об исключении, потоке, методе, сборке, стеке вызовов(!!!)
C> throw;
C>}
C>
А ничего что то, что ты написал к logger::log(__filename__, __line__, "log text") не имеет вообще никакого отношения даже близко.
C>Не позорьтесь так больше.
Как же ты любишь эту фразу.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Scott Meyers is one of the leading gurus in the C++ languages, in his book "Effective C++", the "is a" relationship for public inheritance is being mentioned in item 35: Make sure public inheritance models "is a".
Beside that, the current chairman of the ISO C++ Standard Committee, Herb Sutter, have also mentioned that in one of his articles.
We need "controlled polymorphism" LSP IS-A, but in certain code only. Public inheritance should always model IS-A as per the Liskov Substitution Principle (LSP).[3] Nonpublic inheritance can express a restricted form of IS-A, even though most people identify IS-A with public inheritance alone. Given class Derived : private Base, from the point of view of outside code, a Derived object IS-NOT-A Base, and so of course can't be used polymorphically as a Base because of the access restrictions imposed by private inheritance. However, inside Derived's own member functions and friends only, a Derived object can indeed be used polymorphically as a Base (you can supply a pointer or reference to a Derived object where a Base object is expected), because members and friends have the necessary access. If instead of private inheritance you use protected inheritance, then the IS-A relationship is additionally visible to further-derived classes, which means subclasses can also make use of the polymorphism.
C>>>А как просто вам при вызове логгера указать текущее имя файла, исходника я имею ввиду,ай как вы ругали макросы, это так, это сяк, а как вы напишете: C>>>logger::log(__filename__, __line__, "log text")
C>>
C>>catch(Exception e) {
C>> Log.Error(e); // через рефлексию будет собрана информация об исключении, потоке, методе, сборке, стеке вызовов(!!!)
C>> throw;
C>>}
C>>
CC>А ничего что то, что ты написал к logger::log(__filename__, __line__, "log text") не имеет вообще никакого отношения даже близко.
Конечно имеет. Но если хотите один в один, то ради бога:
Log.Info("log text");