Это не так очевидно в C ++ / CLI, но работает точно так же, как в C #. Вы можете увидеть это, когда посмотрите на класс с помощью Object Browser. Или декомпилятор, такой как ildasm.exe, лучший способ узнать, что он делает.
Когда вы пишете деструктор, компилятор C ++ / CLI автоматически генерирует кучу кода. Он реализует одноразовый шаблон, ваш класс автоматически реализует IDisposable, даже если вы не объявили его таким образом. И вы получаете открытый метод Dispose (), защищенный метод Dispose (bool) и автоматический вызов GC :: SuppressFinalize ().
Вы используете delete
в C ++ / CLI для его явного вызова, компилятор вызывает вызов Dispose (). И вы получаете эквивалент RAII в C ++ / CLI, используя семантика стека , компилятор автоматически отправляет вызов Dispose в конце блока области видимости. Синтаксис и поведение, знакомые программистам C ++.
Вы делаете то же самое, что и в C #, если бы класс был написан на C #. Вы вызываете Dispose () для явного вызова, вы используете оператор using
, чтобы неявно вызывать его безопасным для исключения способом.
В остальных случаях применяются те же правила, вам нужен деструктор, когда вам нужно освободить что-то, что не является управляемой памятью. Почти всегда нативный объект, который вы разместили в конструкторе. Учтите, что не стоит беспокоиться, если этот неуправляемый объект небольшой и что GC :: AddMemoryPressure () является очень достойной альтернативой. Однако вы должны реализовать финализатор (!ClassName()
) в таком классе-оболочке. Вы не можете заставить внешний клиентский код вызывать Dispose (), это необязательно, и о нем часто забывают. Вы не хотите, чтобы такой упуск вызывал неуправляемую утечку памяти, финализатор гарантирует, что она все еще освобождена. Обычно самый простой способ написать деструктор - это явно вызвать финализатор (this->!ClassName();
)