【问题标题】:Creating a custom allocator for CHeapPtr (for use with Sqlite)为 CHeapPtr 创建自定义分配器(用于 Sqlite)
【发布时间】:2020-08-25 21:29:17
【问题描述】:

我想使用CHeapPtrsqlite3 创建一些智能指针。 CHeapPtr 默认使用 CCRTAllocator 类,所以我想我只是创建一些自定义分配器类,它们继承自 CCRTAllocator 但覆盖其 Free 方法,以便它们使用正确的清理功能:

class CSqlite3Allocator : public CCRTAllocator
{
public:
    static void Free(_In_ sqlite3* p) throw()
    {
        sqlite3_close_v2(p);
    }
};

class CSqlite3StmtAllocator : public CCRTAllocator
{
public:
    static void Free(_In_ sqlite3_stmt* p) throw()
    {
        sqlite3_finalize(p);
    }
};

现在我可以像这样创建CHeapPtrs:

CHeapPtr<sqlite3, CSqlite3Allocator> psqlite;
CHeapPtr<sqlite3_stmt, CSqlite3StmtAllocator> pstmt;

这些指针似乎工作正常,并且似乎正在调用它们的清理方法。我只是想知道这是否是正确的方法,或者是否有更可接受的方法来创建自定义CHeapPtrs。感谢您的任何意见。

【问题讨论】:

标签: c++ winapi smart-pointers atl allocator


【解决方案1】:

您不需要从CCRTAllocator 继承,分配器应该只是一个新类。可以以 ATL 的COM heap allocator 为例:

class CComAllocator 
{
public:
    static void* Reallocate(void* p, size_t nBytes) throw()
    {
        return ::CoTaskMemRealloc(p, ULONG(nBytes));
    }
    static void* Allocate(size_t nBytes) throw()
    {
        return ::CoTaskMemAlloc(ULONG(nBytes));
    }
    static void Free(void* p) throw()
    {
        ::CoTaskMemFree(p);
    }
};

template <typename T>
class CComHeapPtr :
    public CHeapPtr<T, CComAllocator>
{
public:
    CComHeapPtr() throw()
    {
    }

    explicit CComHeapPtr(T* pData) throw() :
        CHeapPtr<T, CComAllocator>(pData)
    {
    }
};

(为简洁起见,这里的代码稍微缩短了一点)

您实现的方式可以解决,但是您从 CRT 继承分配/重新分配方法,这使得它成为一个危险的组合:无意中您可能会得到 CRT Allocate 和 sqlite Free 并且可能很难确定它下。如果你不打算使用分配方法,你可以把它们存起来或者把ATLASSERT(FALSE)放在那里。

【讨论】:

    猜你喜欢
    • 2014-02-01
    • 2013-07-30
    • 1970-01-01
    • 1970-01-01
    • 2015-11-20
    • 1970-01-01
    • 1970-01-01
    • 2010-11-13
    • 1970-01-01
    相关资源
    最近更新 更多