Каковы правила подсчета ссылок для reinterpret_cast от необработанных указателей к заштрихованным?

Если я использую reinterpret_cast для преобразования IInspectable* в Object^, несу ли я ответственность за выпуск исходного IInspectable*?

Ясно, что созданный Object^ освободится, когда выйдет за пределы области видимости, поэтому реальный вопрос заключается в том, подразумевает ли reinterpret_cast AddRef, который дает Object^ собственный счетчик ссылок, или он берет на себя ответственность за ссылку, которая у меня уже есть.

Кажется, есть аргументы, которые следует ожидать в любом случае: с одной стороны, операция COM никогда не должна брать на себя счетчики ссылок своих входных указателей, с другой стороны, имя reinterpret_cast предполагает, что она просто переинтерпретирует мои биты от «необработанного указателя ABI» до «указателя в шляпе, который уже владеет ссылкой на объект», и моя работа будет заключаться в том, чтобы убедиться, что это имеет смысл).


person hmakholm left over Monica    schedule 03.04.2013    source источник


Ответы (1)


Сам вызов reinterpret_cast<Object^>(iinsp) не будет иметь побочных эффектов, связанных с подсчетом ссылок, однако присвоение результата этого приведения переменной Object^ приведет к возникновению addref для объекта, на который указывает исходный IInspectable. Когда эта переменная Object^ выходит за пределы области видимости или ей присваивается значение null, для базового объекта также вызывается Release(). Приведет ли это к тому, что объект выйдет за пределы области действия или нет, будет зависеть от его внутреннего счетчика ссылок до всего этого дела. Например:

void foo(IInspectable* p) {  //assume: this comes in with a single refcount
  p->AddRef(); // refcount now 2
  reinterpret_cast<Object^>(p); //refcount still 2
  {
    Object^ o = reinterpret_cast<Object^>(p); //refcount now 3
  } //o goes out of scope, refcount now 2

  p->Release(); // refcount now 1
} //refcount is still 1, the caller of function foo is responsible for cleaning him up
person Andy Rich    schedule 11.04.2013
comment
В этом есть смысл, в совокупности. Я все еще не понимаю, как это понимать на уровне языкового юриста, хотя очевидно, что оценка reinterpret_cast выражения приведет к что-то; что это за штука? Я предположил, что это нечто было анонимным, но в остальном полностью функциональным Object^, который имел свой собственный счетчик ссылок и прекратит существование - и, следовательно, освободит свой счетчик ссылок - после выполнения прилагаемого выражения присваивания. (или, когда reinterpret_cast появляется в пустом контексте, немедленно). - person hmakholm left over Monica; 12.04.2013
comment
В общем, я думаю, что reinterpret_cast довольно глуп. Он просто заставляет компилятор принимать необработанное значение указателя, игнорировать исходный тип и заставлять его полагать, что это целевой тип, даже если эти два типа не связаны. Это опасно в общем случае, но допустимо в данном конкретном случае (IInspectable ‹-> Object^), потому что эти типы имеют одинаковую компоновку. - person Andy Rich; 12.04.2013
comment
Добавление счетчика ссылок из-за приведения кажется ненужным; если временное будет существовать только до конца выражения, то зачем ему дополнительный цикл refcount/release? Если бы компилятор вел себя таким образом, я бы подумал, что это ошибка. - person Andy Rich; 12.04.2013