Задаюсь похожим вопросом: зачем нам 3 метода в интерфейсе вместо 2-х? QueryInterface и Release должно быть достаточно. QI уже выполняет AddRef, и теоретически, если у нас есть 2 метода, используемых для выполнения практически одной и той же работы, один из них следует исключить. QI делает свое дело плюс AddRef. AddRef делает только AddRef. АддРеф умирает. ЦЕЛОВАТЬ.
Теперь, что касается возвращаемого типа, я не согласен с комментарием о том, что AddRef/Release никогда не может дать сбой. Что ж, они могут. По-разному, и они должны следовать одному и тому же правилу возврата HRESULT и результатов в параметрах.
Один из способов, с помощью которого AddRef может потерпеть неудачу, заключается в том, что вы можете превысить ULONG_MAX (трудно достижимо, но возможно). Или семафор, который используется для обеспечения потокобезопасности этого вызова, может вызвать исключение. На самом деле так много вещей может пойти не так, что единственная причина, по которой я могу представить, что в спецификации это было просто ULONG(void), - это производительность, поскольку гораздо проще вызывать метод без параметров.
Производительность клиента была вещью еще в 90-х годах, сейчас она определенно не имеет значения (если вы не говорите об ограниченном клиенте, таком как мобильное устройство). Пожертвовав семантикой во имя производительности, COM-дизайн фактически создал долгосрочную нагрузку на техническое обслуживание за счет краткосрочного выигрыша в производительности, о котором все знали и знают, что он всегда уходит (закон Мура, емкость удваивается каждые 18 секунд). месяцев по той же цене).
Но даже в этом случае AddRef не следует вызывать так часто. Это означает, что вы носите один и тот же объект по нескольким частям вашей системы, что само по себе является явным признаком плохого дизайна.
Я также не согласен с тем, что это плохой вопрос. Это хороший вопрос, потому что он заставляет людей задуматься. SO — это ответы на конкретные вопросы, потому что люди застревают. Тем не менее, заставляя людей думать над широкими/открытыми вопросами, вы обучаете их навыкам, которые в первую очередь предотвратят их застревание.
person
See Sharper
schedule
12.04.2018
AddRef
иRelease
не могут выйти из строя, поэтому нет смысла заставлять их возвращатьHRESULT
. Что касается вашего последнего вопроса: методы[local]
не должны вернутьHRESULT
(хотя могут, если захотят); все остальные методы должны возвращатьHRESULT
. Это связано с тем, что уровень маршалинга должен иметь возможность сообщать о своих собственных ошибках (например, о сбое сети, если вызов выходит за пределы машины, а удаленный хост недоступен).AddRef
иRelease
это[local]
- person Igor Tandetnik   schedule 22.01.2014AddRef()
. Например, предположим, что у клиента есть указатель локального интерфейса, который будет назначен действительным указателем интерфейса, возвращаемым сервером. А если и клиент, и сервер — это два разных процесса, их адресные пространства тоже будут разными. Таким образом, еслиpIOne
отправляется сервером, аpIOneTemp
является локальным, то после оператораpIOneTemp = pIOne;
клиенту придется вызыватьAddRef()
наpIOneTemp
просто потому, что он находится в совершенно другом адресном пространстве. Теперь, почему он не должен возвращатьHRESULT
? - person user2705939   schedule 23.01.2014HRESULT
, только его собственные методы IUnknown не следуют правилу. Также см. мой комментарий выше, и, пожалуйста, объясните, что если возникнет такой случай? - person user2705939   schedule 23.01.2014AddRef
. Как вы думаете, какую часть моего комментария можно истолковать таким образом? Если бы клиенту никогда не приходилось вызыватьAddRef
, то интерфейсIUnknown
изначально не предоставлял быAddRef
. Но какое отношение все это имеет к возвращениюHRESULT
? Есть ли в книгах закон о том, что любой метод, который можно вызвать, должен возвращатьHRESULT
? - person Igor Tandetnik   schedule 23.01.2014pOne
на самом деле является указателем на прокси, созданный уровнем маршалинга COM и находящийся в вашем процессе.pOne->AddRef()
вызываетAddRef
на этом прокси - этот вызов никогда не направляется на удаленный сервер. Как я уже сказал,AddRef
иRelease
являются[local]
методами. Дополнительные сведения см. в разделе msdn.microsoft.com/en-us. /библиотека/окна/рабочий стол/ms693719.aspx - person Igor Tandetnik   schedule 23.01.2014