Здравствуйте, IT, Вы писали:
IT>И как я понимаю, для агрегированных значений тоже генерируется вызов Dispose, если они его поддерживают? А если у меня агрегированный объект is object or ArrayList?
Ценное замечание. Нужно срочно сообщить в группу разработки, чтобы они пытались приводить все возможные варианты к диспозу. Ну, на всякий пожарный.
Но вообще-то ПК прав. Интеграция реализации паттернов в язык — это правильно. Чем меньше нужно думать, тем лучше. Все эти навороты по реализации диспоза отнюдь не радуют. Радует, только то что их крайне редко приходится реализовывать вручную. А использование упрощается юсингом (тоже, кстати, встроенная поддержка паттерна).
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2,
> IT> И как я понимаю, для агрегированных значений тоже генерируется вызов Dispose, если они его поддерживают? А если у меня агрегированный объект is object or ArrayList?
> Ценное замечание. Нужно срочно сообщить в группу разработки, чтобы они пытались приводить все возможные варианты к диспозу. Ну, на всякий пожарный.
Так делать нельзя: Object нельзя хранить "по значению", следовательно остается только ссылка/указатель. В этом случае никакой уверенности, что класс, содержащий ссылку, является владельцем объекта, нет. Так можно запросто разрушить чужие данные.
> Все эти навороты по реализации диспоза отнюдь не радуют. Радует, только то что их крайне редко приходится реализовывать вручную.
Недавно на работе ребята полтора дня искали ошибку. Нашли: не вызывался Dispose. Кажется, для одного из членов класса. Finalize был абсолютно бесполезен, т.к. в этом Dispose объект должен был удалять себя из некоего реестра. Т.к. этого не происходило, ссылка на него жила (в реестре), и Finalize, очевидно, никогда не мог быть вызван.
Другая проблема — сохранение инвариантов при возникновении исключений. Т.к. в C# на уровне языка поддержки для автоматизации транзакций нет (худо-бедно, но обеспечиваемой в C++ деструкторами), в итоге после "неожиданного" исключения программа легко может просто перестать работать. Она обычно не вылетает, но и правильно не работает. Вот такие пироги...
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Недавно на работе ребята полтора дня искали ошибку. Нашли: не вызывался Dispose. Кажется, для одного из членов класса. Finalize был абсолютно бесполезен, т.к. в этом Dispose объект должен был удалять себя из некоего реестра. Т.к. этого не происходило, ссылка на него жила (в реестре), и Finalize, очевидно, никогда не мог быть вызван.
Мне интересно, эта ошибка была ошибкой проектирования? То есть от Dispose'ов ожидалось поведение сишных деструкторов? Или я не понял о чем речь?
Там есть существенная неточность в отношении Dispose и Finalize применительно к C++/CLI:
The Dispose(bool) pattern still must be done.
В релизе Whidbey Dipose Pattern будет реализовываться компилятором автоматически. Более того, руками там особо ничего не сделаешь: программа на C++/CLI не сможет явно вызывать функции Dispose(), Dispose(bool) и Finalize(), если они перекрывают функции System::Object::IDisposable::Dispose и System::Object::Finalize.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
>> Ценное замечание. Нужно срочно сообщить в группу разработки, чтобы они пытались приводить все возможные варианты к диспозу. Ну, на всякий пожарный.
ПК>Так делать нельзя:...
Пашь, ну, хоть чуть-чуть юмора то нужно иметь.
ПК>Недавно на работе ребята полтора дня искали ошибку. Нашли: не вызывался Dispose. Кажется, для одного из членов класса. Finalize был абсолютно бесполезен, т.к. в этом Dispose объект должен был удалять себя из некоего реестра. Т.к. этого не происходило, ссылка на него жила (в реестре), и Finalize, очевидно, никогда не мог быть вызван.
У вас случаем на работе фины не работают? Полтора дня искать такую ошибку — это достойно книги гинеса.
ПК>Другая проблема — сохранение инвариантов при возникновении исключений. Т.к. в C# на уровне языка поддержки для автоматизации транзакций нет (худо-бедно, но обеспечиваемой в C++ деструкторами), в итоге после "неожиданного" исключения программа легко может просто перестать работать. Она обычно не вылетает, но и правильно не работает. Вот такие пироги...
Пошь, это уже просто клинический случай предвзятости. Если бы все было как ты описывашь, то все по прежнему писали бы на плюсах и никто на шарп даже не взглянул.
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Хитрик Денис, Вы писали:
ХД>Мне интересно, эта ошибка была ошибкой проектирования? То есть от Dispose'ов ожидалось поведение сишных деструкторов? Или я не понял о чем речь?
Дуамаю это проблемы ментолитета. Когда человек 10 лет вынужден был особождать ресурсы, то даже будучи освобожденным от этого он по привычке продолжает строить свой код подобным образом.
В общем, пора писать статью "Жизть после того как память перестала быть ресурсом".
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2,
> ХД> Мне интересно, эта ошибка была ошибкой проектирования? То есть от Dispose'ов ожидалось поведение сишных деструкторов? Или я не понял о чем речь?
> Дуамаю это проблемы ментолитета. Когда человек 10 лет вынужден был особождать ресурсы, то даже будучи освобожденным от этого он по привычке продолжает строить свой код подобным образом. В общем, пора писать статью "Жизть после того как память перестала быть ресурсом".
LOL. Один из людей, о которых идет речь, к "плюсам" уже как минимум несколько лет не прикасался, пожалуй, за исключением чтения и мелких правок, и в языках, с которыми он в основном работает, управлять памятью не приходится и близко. Просто (естественно) хочется сделать так, чтобы язык хоть как-то помогал автоматизировать работу, а не выписывать многочисленные паттерны вручную.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Там есть существенная неточность в отношении Dispose и Finalize применительно к C++/CLI: ПК>
ПК>The Dispose(bool) pattern still must be done.
ПК>В релизе Whidbey Dipose Pattern будет реализовываться компилятором автоматически. Более того, руками там особо ничего не сделаешь: программа на C++/CLI не сможет явно вызывать функции Dispose(), Dispose(bool) и Finalize(), если они перекрывают функции System::Object::IDisposable::Dispose и System::Object::Finalize.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>LOL. Один из людей, о которых идет речь, к "плюсам" уже как минимум несколько лет не прикасался, пожалуй, за исключением чтения и мелких правок, и в языках, с которыми он в основном работает, управлять памятью не приходится и близко. Просто (естественно) хочется сделать так, чтобы язык хоть как-то помогал автоматизировать работу, а не выписывать многочисленные паттерны вручную.
После плюсов слова "чтобы язык хоть как-то помогал автоматизировать работу, а не выписывать многочисленные паттерны вручную" звучат как издевательство. Я тут как раз воюю с Синтиловским кодом...
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>В релизе Whidbey Dipose Pattern будет реализовываться компилятором автоматически. Более того, руками там особо ничего не сделаешь: программа на C++/CLI не сможет явно вызывать функции Dispose(), Dispose(bool) и Finalize(), если они перекрывают функции System::Object::IDisposable::Dispose и System::Object::Finalize.
Слабо в это верится. Всегда можно втупую привести объект к IDispose и вызвать метод.
... << RSDN@Home 1.1.4 beta 4 rev. 359>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
VladD2,
> После плюсов слова "чтобы язык хоть как-то помогал автоматизировать работу, а не выписывать многочисленные паттерны вручную" звучат как издевательство. Я тут как раз воюю с Синтиловским кодом...
Видимо, авторы "Синтиловского кода" "плюсы" готовить не умеют.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
VladD2,
> ПК> В релизе Whidbey Dipose Pattern будет реализовываться компилятором автоматически. Более того, руками там особо ничего не сделаешь: программа на C++/CLI не сможет явно вызывать функции Dispose(), Dispose(bool) и Finalize(), если они перекрывают функции System::Object::IDisposable::Dispose и System::Object::Finalize.
> Слабо в это верится. Всегда можно втупую привести объект к IDispose и вызвать метод.
В C++/CLI (по крайней мере, в текущей спецификации) использовать System::IDisposable напрямую будет нельзя. Компилятор должен будет выдать сообщение об ошибке. Не вижу, как они предполагают обходиться, если будет нужен именно System::IDisposable, но в данный момент это так, как написано выше.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>В C++/CLI (по крайней мере, в текущей спецификации) использовать System::IDisposable напрямую будет нельзя. Компилятор должен будет выдать сообщение об ошибке. Не вижу, как они предполагают обходиться, если будет нужен именно System::IDisposable, но в данный момент это так, как написано выше.
Ну, тогда напиши друзьям занимающимся реализацией этой спецификации, что у них ничего не получилось:
VladD2,
> ПК> В C++/CLI (по крайней мере, в текущей спецификации) использовать System::IDisposable напрямую будет нельзя. Компилятор должен будет выдать сообщение об ошибке. Не вижу, как они предполагают обходиться, если будет нужен именно System::IDisposable, но в данный момент это так, как написано выше.
> Ну, тогда напиши друзьям занимающимся реализацией этой спецификации, что у них ничего не получилось: <...>
См. выделенное выше. Это еще не вошло в билд, который есть у тебя. Но спецификация еще может измениться. И не раз
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
VladD2 пишет:
> ПК>Видимо, авторы "Синтиловского кода" "плюсы" готовить не умеют. > А их умею готовить только гуры и то в примерах. А в раельном где > большого проекта всегда попадается подобная фигня:
А давайте ее чуть-чуть перепишем:
void ScintillaWin::Paste() {
if (!::OpenClipboard(MainHWND()))
return;
ON_BLOCK_EXIT(CloseClipboard,MainHWND());
pdoc->BeginUndoAction();
ON_BLOCK_EXIT_OBJ(*pdoc,ScintillaDocument::EndUndoAction);
int selStart = SelectionStart();
ClearSelection();
bool isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0;
// Always use CF_UNICODETEXT if available
HGLOBAL hmemUSelection = ::GetClipboardData(CF_UNICODETEXT);
if (hmemUSelection) {
wchar_t *uptr = static_cast<wchar_t
*>(::GlobalLock(hmemUSelection));
ON_BLOCK_EXIT(::GlobalUnlock,hmemUSelection);
if (uptr) {
unsigned int len;
std::wstring putf;
unsigned int bytes = ::GlobalSize(hmemUSelection);
putf=std::wstring(uptr,bytes/sizeof(wchar_t));
// Default Scintilla behaviour in Unicode modeif (IsUnicodeMode()) {
if (isRectangular) {
PasteRectangular(selStart, putf.c_str(), len);
} else {
if (pdoc->InsertString(currentPos, putf.c_str(), len)) {
SetEmptySelection(currentPos + len);
}
}
} else {
// CF_UNICODETEXT available, but not in Unicode mode
// Convert from Unicode to current Scintilla code page
std::string converted=convert_from_unicode(putf,
pdoc->dbcsCodePage);
if (isRectangular) {
PasteRectangular(selStart, converted.c_str(), len);
} else {
if (pdoc->InsertString(currentPos,
converted.c_str(), len)) {
SetEmptySelection(currentPos + len);
}
}
}
}
} else {
//I'm bored with it
}
NotifyChange();
Redraw();
}
У меня тут наверняка куча ошибок, но если нормально писать на
современном С++, то код будет выглядеть примерно как у меня.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Торможу. Видимо, смутило использование слова "реализует": для меня это означает какие-то действия по предоставлению реализаций функций, определенных в интерфейсе — с C# мало общаюсь Ладно, это лирика.
Привыкай к терминологии В нете интерфейс это отдельная сущность, а не абстрактный класс, как в плюсах. Поэтому класс не наследует интерфейс, а реализует, и, имхо, это правильно, поскольку наследование реализаций и интерфейсов вещи вобщем то концептуально различные.
ПК>Да, добавление деструктора в ref class добавляет в список базовых интерфейсов неявное наследование от System::IDisposable
Реализацию
ПК>, если его там еще нет. Плюс, если класс унаследован от System::IDisposable
Реализует
ПК>Т.е., скажем, при наследовании от IEnumerable,
Реализации
ПК> который в свою очередь унаследован от IDisposable
А вот здесь правильно.
Это касательно терминологии. Теперь касательно сути — ни в 1.1 ни в 2.0 IEnumerable от IDisposable не наследуется.
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Недавно на работе ребята полтора дня искали ошибку. Нашли: не вызывался Dispose. Кажется, для одного из членов класса. Finalize был абсолютно бесполезен, т.к. в этом Dispose объект должен был удалять себя из некоего реестра. Т.к. этого не происходило, ссылка на него жила (в реестре), и Finalize, очевидно, никогда не мог быть вызван.
WeekReference спасет ваших отцов русской демократии
AndrewVK,
> Привыкай к терминологии В нете интерфейс это отдельная сущность, а не абстрактный класс, как в плюсах. Поэтому класс не наследует интерфейс, а реализует
Это в C#. В C++/CLI взаимозаменяемо используют "наследует" и "реализует". Более того, в C++/CLI интерфейс CLI называется интерфейсным классом
> и, имхо, это правильно, поскольку наследование реализаций и интерфейсов вещи вобщем то концептуально различные.
Далеко не всегда хочется разделять наследование от ref класса и от interface класса. Например:
template< typename T >
ref class C : public T
{
. . .
};
здесь в качестве T может быть как ref class, так и interface class (а в будущем — и просто class), и все время мучиться выговаривая "базовый ref класс или реализуемый интерфейс" никакой выгоды, по-моему, не дает. А в будущем еще и придется все эти места поправить, добавив "или класс". В общем, я пока не вижу большого смысла в постоянном подчеркивании различия между наследованием от ref class, interface class и class.
> Теперь касательно сути — ни в 1.1 ни в 2.0 IEnumerable от IDisposable не наследуется.
Не расширяет?
Видимо, ошибочка в примере вышла. С другой стороны, для сути совершенно неважно, какой именно интерфейс был бы приведен в качестве примера — это не суть, а несущественная деталь. Можно взять IEnumerator<T>, который таки наследуется от (расширяет ?) IDisposable. Суть-то не в том, что облегчается реализация классов, реализующих (экая тавтология получается ) IEnumerable, а в том, что облегчается реализация классов, (возможно косвенно) наследующих (так в данном случае, имхо, звучит приятнее ) IDisposable.
Posted via RSDN NNTP Server 1.9
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен