
![]() |
Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
|
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[216.73.216.52] |
![]() |
|
Страницы: (117) « Первая ... 109 110 [111] 112 113 ... 116 117 ( Перейти к последнему сообщению ) |
Сообщ.
#1651
,
|
|
|
Цитата Собственно, я говорил именно об этом Тип-то выяснить можешь, но это не тот, что у тебя есть. Да, совершенно верно. Правда я когда-то делал, чтобы можно было именно работать с "чужими" классами, и даже инстанцировать их в рамках своего модуля, но это все уж очень грязно, и к тому же не решает всех проблем. Так как вызвать статический метод именно чужого класса невозможно никак. Вот тут интерфейсы и нужны, так как интерфейсный тайпкаст - глобальный ![]() Добавлено Цитата А у вас разный что ль? А почему? Потому что ваш с COM не совместим был что ль? Потому что читай выше. ![]() |
![]() |
Сообщ.
#1652
,
|
|
Ну как тебе сказать. Ну вот в Delphi ключевое слово object часто используется? Вот в С++ NTBS используется столь же часто. В С++ используется класс string. Под словами "используется" я подразумеваю, что все адекватные люди используют этот класс, если только что-то серьёзное не вынуждает их использовать NTBS. А Си тут при чём? ![]() |
Сообщ.
#1653
,
|
|
|
Цитата Да ты объясни мне, нахрена его назначать то? А ты объясни мне зачем столько разных реализаций простого типа строк? Одни затыкают дыры других, что ли? Цитата А Си тут при чём? Ну ты же споришь с тем, что это пошло именно из Паскаля? А откуда по-твоему? Из C? |
![]() |
Сообщ.
#1654
,
|
|
Цитата --Ins-- @ Ну ты же споришь с тем, что это пошло именно из Паскаля? А откуда по-твоему? Из C? Что именно? Reference-counting у строк? Это пошло от предназначения языка(Pascal). Цитата --Ins-- @ А ты объясни мне зачем столько разных реализаций простого типа строк? Одни затыкают дыры других, что ли? Не совсем. Я тебе могу расписать предназначение каждой из перечисленных мною реализаций, но чуть позже, нужно отойти. |
Сообщ.
#1655
,
|
|
|
Ты же знаешь Qt. И, подозреваю, гораздо лучше, чем я ![]() И ты у меня это спрашиваешь? ![]() Насколько я знаю, там применен межанизм отложенного копирования. То есть, когда ты присваиваешь строку другой переменной, это не означает копирования собственно строки. Копия собственно массива символов создается при изменении этой второй переменной. Для явного же копирования есть QDeepCopy. Отсюда и засада: передал строку в другой поток - это не значит, что собственно выделенная память для массива строки разделилась, и при использовании вроде бы разных переменных можно работать с одной и той же строкой... Я правильно сказал? Я могу взять пирожок? Добавлено Цитата archimed7592 @ Да ты объясни мне, нахрена его назначать то? Вот возьми Java - не так давно wind озвучивал немалые цифры о кол-ве интерфейсов/классов в крупных проектах. Я точно не припомню, но мне даже для сотни(а там что-то вроде десятков тысяч было) интерфейсов было бы лень эти IID'ы назначать. Тебе это уже давно пытаются объяснить: для опознавания интерфейса при отсутствии RTTI. Потому что интерфейс может придти, вообще говоря, из другого языка. А писать объявления классов не лень? Что там сложного-то, в назначении IID? Они либо автоматом, либо три пальца на клавиатуру положить. |
Сообщ.
#1656
,
|
|
|
Цитата Что именно? Reference-counting у строк? Прочти выше, не хочу повторяться. ![]() Цитата Насколько я знаю, там применен межанизм отложенного копирования. То есть, когда ты присваиваешь строку другой переменной, это не означает копирования собственно строки. Копия собственно массива символов создается при изменении этой второй переменной. Для явного же копирования есть QDeepCopy. Отсюда и засада: передал строку в другой поток - это не значит, что собственно выделенная память для массива строки разделилась, и при использовании вроде бы разных переменных можно работать с одной и той же строкой... Romkin, в Delphi ведь точно так же. Но там тип string абсолютно потокобезопасен, так как при передаче ссылки в другой поток - RefCount увеличивается, и попытка ее изменения из любого потока приведет к тому, что этому коду будет предоставлена своя копия. |
Сообщ.
#1657
,
|
|
|
Цитата --Ins-- @ Romkin, в Delphi ведь точно так же. Но там тип string абсолютно потокобезопасен, так как при передаче ссылки в другой поток - RefCount увеличивается, и попытка ее изменения из любого потока приведет к тому, что этому коду будет предоставлена своя копия. Ты уверен, что потокобезопасен? То, что делается практически так же - это да ![]() Но поток-же не знает, откуда пришла строка, и я не слышал, чтобы что-то делалось для этого. Изменение RefCount и копирование строки - не атомарная операция, и можно напороться, что пока один поток копирует - другой туда пишет. Или оба копируют. |
Сообщ.
#1658
,
|
|
|
Цитата Изменение RefCount и копирование строки - не атомарная операция Изменение RefCount - атомарная. ![]() ![]() function _LStrAddRef(var str): Pointer; var P: PStrRec; begin P := Pointer(Integer(str) - sizeof(StrRec)); if P <> nil then if P.refcnt >= 0 then InterlockedIncrement(P.refcnt); // !! Result := Pointer(str); end; Так что при копировании строки оба потока будут обладать правильной информацией о счетчике ссылок и вести себя корректно. Добавлено Цитата Но поток-же не знает, откуда пришла строка Если у потока своя ссылка - то увеличение RefCount произойдет в любом случае. А если он используют глобальную ссылку совместно с другими потоками - то это уже проблема не строк, а использования любых глобальных данных из разных потоков |
Сообщ.
#1659
,
|
|
|
Тут проблема как раз в том, что неатомарна вся операция копирование-изменение RefCount. И если ты присвоил глобальную переменную локальной - это не значит, что сама строка перестала быть глобальной. А с integer, например, такого не произойдет.
Смотри: один поток присвоил значение глобальной строке и сообщил другому. Второй присваивает эту переменную своей локальной и сообщает первому, что глобальная свободна. А на самом деле - нет. Просто счетчик увеличился. Впрочем, у Delphi здесь действительно соломку подстелили: при изменении символа идет неявный вызов UniqueString. |
Сообщ.
#1660
,
|
|
|
Цитата Romkin @ Тебе это уже давно пытаются объяснить: для опознавания интерфейса при отсутствии RTTI. Потому что интерфейс может придти, вообще говоря, из другого языка. Из какого "другого"? Т. е. если я веду разработку исключительно в Delphi, и COM со всем остальным мне нафиг не сдался, то мне все равно надо задумываться над тем, что "а вдруг я будут пользовать интерфейсы, писанные на С++!!! ![]() ![]() ![]() В C# вся COM-кухня вынесена в COMInterop. В java - тоже в соответствующие библиотеки. Уверен, что всяческие питоны, пхп и прочие звери имеют опциональные биндинги к COM/CORBA/голому RPC. И только Delphi обязывает программиста заботиться о чем-то, что ему может нафиг не понадобиться? ![]() ![]() ![]() |
Сообщ.
#1661
,
|
|
|
Цитата при изменении символа идет неявный вызов UniqueString. В том то и дело. Хоть потоки и ссылаются на один и тот же массив байт в памяти, попытка изменения его любым потоком не испортит данные другого. Будет определено, что число ссылок на строку больше единицы и будет вызван UniqueString. Собственно именно для этого и введен подсчет ссылкок - чтобы реализовать механизм копирования по необходимости. Добавлено Цитата Из какого "другого"? Т. е. если я веду разработку исключительно в Delphi, и COM со всем остальным мне нафиг не сдался, то мне все равно надо задумываться над тем, что "а вдруг я будут пользовать интерфейсы, писанные на С++!!! " Ну нахрена, спрашивается? Во всех нормальных языках есть прозрачная поддержка интерфейсов, runtime-типизации и прочих подобных механизмов, специфичиных для языка. И только в Delphi программист должен явным образом заботиться о том, чтобы язык и среда выполнения не попутала его интерфейс с каким-нибудь другим, а потому обязан навесить на интерфейс UUID. Тут согласен. Можно было бы действительно сделать так, что если IID явно не назначен, различать интерфейсы по некоторым другим параметрам. А то интерфейсы без IID в Delphi слегка кастрированы... Но это уже проблема конкретного компилятора, а не языка. |
Сообщ.
#1662
,
|
|
|
Цитата --Ins-- @ Тут согласен. Можно было бы действительно сделать так, что если IID явно не назначен, различать интерфейсы по некоторым другим параметрам. А то интерфейсы без IID в Delphi слегка кастрированы... Ну вот... ![]() ![]() ![]() |
Сообщ.
#1663
,
|
|
|
Цитата И эти люди критикуют C++, основной принцип которого Я критикую C++ лишь за то, что основной принцип этого языка - вседозволенность, которая на мой взгляд не нужна ВЫСОКОУРОВНЕВОМУ ЯП, тем более - объектному. И как следствие - отсутствие всякой логики, наличие неоднозначностей и противоречий. На мой взгляд - это один из худших языков, реализующий концепцию императивного программирования. Причина этому возможно субъективна. Паскалевское воспитание, которое приучает к дисциплине в программировании. |
Сообщ.
#1664
,
|
|
|
Цитата Flex Ferrum @ Т. е. если я веду разработку исключительно в Delphi, и COM со всем остальным мне нафиг не сдался, то мне все равно надо задумываться над тем, что "а вдруг я будут пользовать интерфейсы, писанные на С++!!! Нет. Просто интерфейсы изначально предельно оторваны от реализации. И Delphi не важно, как и когда был написан программный модуль, из которого взят интерфейс. То есть, допустим, у меня есть dll, из которой я получаю ссылку интерфейс (неважно, каким способом). Мне совершенно не интересно, на какой версии компилятора Delphi написана эта библиотека, да и на Delphi ли. Компилятор будет, опираясь на имеющееся описание интерфейса в моем модуле, работать с полученной ссылкой. А какое описание брать - он поймет по IID. А если бы он присваивался автоматом - я бы так сделать не смог, пришлось бы брать из этой библиотеки еще и RTTI, и заботиться о том, какой она версии и так далее. Причем использовать данный интерфейс я могу вполне полноценно, включив его, например, в свою реализацию. Все, что нужно для этого - описание интерфейса плюс способ получить его реализацию. |
Сообщ.
#1665
,
|
|
|
Цитата --Ins-- @ А ты объясни мне зачем столько разных реализаций простого типа строк? Одни затыкают дыры других, что ли? Нет. Ты, как программист со стажем, должен понимать, что грамотных универсальных реализаций фундаментальных сущностей (наподобие строк) не бывает и быть не может. Потому как разработчик такой реализации просто физически не может предусмотреть всех хотелок тех, кто ею будет пользоваться. А поскольку спектр применения того же С++ очень широк (от драйверов до сложнейших enterprise-серверов), то учесть все, что может понадобиться и всех особенностей, которые должны быть учтены, просто невозможно. По этому стандартный класс (который std::basic_string) реализует необходимый минимум функционала, который может потребоваться от строк, дабы покрыть наиболее широкий спектр задач, в которых он может понадобиться (следуя тому же принципу zero-cost features). Различного рода специализированные библиотеки (наподобие того же Qt или xerces) предлагают свои реализации строки, которые содержат функции, специфичные для той предметной области, в которой эти библиотеки будут применяться. Например, Qt предлагает широкий набор функций для различных преобразований строк, их форматирования и прочее. Что, собственно, и требуется от UI-библиотеки. В xerces делается упор на преобразование между разными кодировками и разными представлениями строки, что и требуется от XML-парсера. И т. д. |