Могу ли я остановить C ++ / CLI от добавления IDisposable в мой класс ref? - PullRequest
6 голосов
/ 05 февраля 2009

C ++ / CLI полезно создает леса IDisposable для вас, когда вы реализуете деструктор в классе ref. Кроме того, если вы не реализуете деструктор, но в вашем классе есть переменная-член, которая реализует IDisposable, тогда IDisposable снова автоматически реализуется в вашем классе. Это довольно полезно и намного лучше, чем то, как IDisposable обрабатывается в C #.

Я столкнулся с таким поведением при реализации класса ref, который содержит msclr::com::ptr (умный указатель, содержащий RCW).

ref class Test /* : IDisposable added by the compiler */
{
  msclr::com::ptr<IWhatever> _aComObject;
}

В моем конкретном случае COM-объект, на который ссылается мой класс, не блокирует некоторый неуправляемый ресурс, он фактически просто использует немного неуправляемой памяти, которую CLR не видит. Поэтому я хотел бы избежать путаницы с пользователями моего класса ref, не реализовав IDisposable класс. Вместо этого я хочу, чтобы CLR знал о существовании COM-объекта, используя GC API для добавления соответствующего давления памяти.

Итак, вопрос в следующем: есть ли способ подавить реализацию IDisposable в классе ref, который не реализует деструктор, но содержит переменную-член IDisposable?

NB: часто это было бы неправильно, так как это не позволило бы пользователям класса детерминистически избавиться от базового COM-объекта, но, учитывая конкретные обстоятельства, разоблачение IDisposable имеет возможность сбить с толку пользователей моего класса ref, поскольку в действительности нет необходимости избавляться от рассматриваемого класса ref.

Полагаю, одним из вариантов было бы реализовать вариант msclr :: com :: ptr без деструктора.

Был бы признателен любой другой метод для подавления автоматического добавления IDisposable. Спасибо.


Ответ

Объявите _aComObject как дескриптор msclr :: com :: ptr (msclr::com::ptr<IWhatever>^). Компилятор не считает Test «владельцем» объекта com ptr и не удаляет его при удалении Test.

Ответы [ 2 ]

2 голосов
/ 06 февраля 2009

Я думаю, что ответом является удержание дескриптора в msclr :: com :: ptr вместо удержания его «по значению» (которое по-прежнему удерживает его как дескриптор «за кулисами», за исключением того, что компилятор CLI C ++ рассматривает его как значение - «удаляя» его (вызывая Dispose) при удалении объекта-владельца (Disposed)).

1 голос
/ 06 февраля 2009

Я не уверен, что согласен с коэффициентом, позволяющим избежать реализации IDispose - но почему бы просто не сохранить IWh независимо * в вашем классе. Компилятор не должен генерировать реализацию IDisposable.

Если вы не хотите, чтобы поведение деструктора приносило вам пользу от использования оболочки com :: ptr? Вы всегда можете объявить com :: ptr в стеке и назначить ему указатель на член в любом данном методе, если он вам действительно нужен.

...