уникальный ptr — опасности неявного преобразования C ++

Я пишу некоторый контейнер с управляемой ручкой, не похожий на std::unique_pointer (хотя я не писать свой код на C ++ 11 пока нет). У меня есть что-то вроде этого:

template <class H>
class UniqueHandle {
H h;

public:
UniqueHandle(H _h = 0) // "the first constructor", referred below
:h(_h) {}

UniqueHandle(UniqueHandle &other)
:h(other.YieldOwnership()) {}

~UniqueHandle() { ::DeleteHandle(h); }

UniqueHandle &operator =(UniqueHandle &other)
{
::DeleteHandle(h); // release the old handle
h = other.YieldOwnership();
return *this;
}

UniqueHandle &operator =(H _h)
{
::DeleteHandle(h); // release the old handle
h = _h;
return *this;
}

H YieldOwnership() { H result = h; h = 0; return result; }

operator H() const { return h; }
};

Может быть куча других операторов, но давайте будем проще. Теперь давайте предположим:

typedef int HANDLE;

void DeleteHandle(HANDLE h)
{
cout << "deleting handle " << h << endl;
}

int main()
{
UniqueHandle<HANDLE> h(123);
UniqueHandle<HANDLE> h2 = 456;
HANDLE unmanaged = 789;
HANDLE mixed_case = (rand() & 1)? (HANDLE)h : unmanaged;
DeleteHandle(unmanaged);
return 0;
}

Я пытался запустить это на ideone, и работает как положено. Однако в Visual Studio (2008) mixed_case не требует преобразования h обнажать HANDLE и вместо этого неявно преобразует unmanaged в UniqueHandle<HANDLE>, что вызывает его удаление вскоре после. Мне потребовалось некоторое время, чтобы найти эту ошибку, и я знаю, что ее можно исправить, объявив первый конструктор как explicit,

Мой вопрос: являются operator = одинаково опасно? С какими еще опасностями можно столкнуться с этими типами уникальных менеджеров ресурсов?

2

Решение

Задача ещё не решена.

Другие решения


По вопросам рекламы [email protected]