C ++隐式转换的危险

时间:2014-10-30 13:05:05

标签: c++ unique-ptr resource-management

我正在编写一些托管句柄容器,与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>,不久后导致删除。我花了一些时间来找到这个bug,我知道可以通过将第一个构造函数声明为explicit来修复它。

我的问题是operator =同样危险吗?使用这些类型的独特资源管理器可能会遇到哪些其他风险?

0 个答案:

没有答案