Я проверял чей-то код, и я увидел это:
template<typename Data>
class ConcurrentQueue {
private:
HANDLE dataPushEvent;
// More Private Members...
public:
ConcurrentQueue() {
dataPushEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
}
// Public Methods...
};
Как вы можете видеть, в этом классе нет деструктора, и dataPushEvent
явно не освобождается нигде в этом классе. Поскольку это частный член, он не может быть использован снаружи, поэтому я думал, что это, вероятно, приведет к утечке памяти.
Если этот дескриптор не должен быть удален.
Я новичок в программировании C++ и Windows. Насколько мне известно, HANDLE
- это void *
, и, как и все указатели, ее ссылка должна быть выпущена, когда мы закончили ее использование.
Я прав?
Если нет деструктора, то да, ручка просочилась. Для уничтожения события должен быть деструктор, вызывающий CloseHandle()
.
В качестве побочного примечания класс должен также удалить (С++ 11) или сделать недоступным (С++ 03) конструктор копирования и операторы присваивания копий, так как значения по умолчанию для компилятора не будут иметь смысла - они, скорее всего, скопируют в очереди, но все же ссылаются на один и тот же дескриптор события, заставляя несколько кажущихся независимыми очередей разделить событие без уважительной причины. И когда вы реализуете деструктор, реализация копии по умолчанию будет еще хуже, потому что, как только одна копия будет уничтожена, она уничтожит дескриптор события, который все еще используется всеми другими копиями!
В С++ 11 вы можете реализовать move-constructor и операторы присваивания move, но вам придется настроить деструктор на учет, чтобы тот факт, что дескриптор мог быть перемещен на другой объект, чтобы он не вызовите CloseHandle()
.
CloseHandle()
должен вызываться дляdataPushEvent
если вы хотите освободить его до завершения процесса.HANDLE
, верно?