我正在使用C ++中的第三方C API集,该讨论涉及两种方法:
我创建了一个自定义分配器,包含the_api_malloc()和the_api_free()以用于例如std :: vector。这很有效。
我想要做的是有一个std :: vector类,它使用我的自定义分配器,但也有一个release()方法,在调用时,释放它的内存所有权,因此不会调用我的自定义分配器the_api_free ()。
pointer release() /* pointer is of T* */
使用示例:
MyClass myClass(1024); // the_api_malloc()'s 1024 bytes
// ... do something with myClass
the_api_give_back(myClass.release());
我不确定最好的解决方法。我现在所做的一个实验是相当讨厌的:
class MyClass : public std::vector<char, MyAllocator<char> > {
public:
using typename std::vector<char, MyAllocator<char> >::pointer;
pointer release() {
// note: visual studio impl.
pointer p = this->_Myfirst;
this->_Myfirst = 0;
this->_Mylast = 0;
this->_Myend = 0;
return p;
}
}
有更好的方法吗?
更新1 :以下是我根据以下建议尝试的内容。这也应该有助于说明所需的行为和它目前失败的地方。
template <class T>
class MyAllocator
{
public:
// types omitted for clarity
MyAllocator() : m_released(false) { }
template <class U>
MyAllocator(MyAllocator<U> const& a) : m_released(a.m_released) { }
// other ctors, dtors, etc. omitted for clarity
// note: allocate() utilizes the_api_malloc()
void deallocate(pointer p, size_type num)
{
if(!m_released) {
the_api_free(p);
}
}
void release_ownership() { m_released = true; }
bool m_released;
};
template <typename T>
char* ReleaseOwernship(T& container)
{
container.get_allocator().release_ownership();
return &container[0];
}
// usage:
{ // scope
std::vector<char, MyAllocator<char> > vec;
// ...do something to populate vec...
char* p = ReleaseOwnership(vec);
the_api_give_back(p); // this API takes ownership of p and will delete it itself
} // end scope - note that MyAllocator::deallocate() gets called here -- m_release is still false
更新2:尝试创建一个MyOwningAllocator和一个MyNonOwningAllocator,然后从拥有到“非发布时间”的非拥有者交换,但无法让swap()工作,因为它们是不同类型。
答案 0 :(得分:1)
我没有尝试停止向量调用分配器的自由函数,而是将release
作为分配器的成员包含在内,并让它设置一个标志。设置标志后,the_api_free
将简单地返回(即充当nop)。
答案 1 :(得分:1)
vector::swap
会将已分配区块的所有权转移给另一个vector
。但是,没有办法阻止向量在其析构函数中调用vector::allocator_type::deallocate
,并且没有可移植的方法来直接修改内部指针。
答案 2 :(得分:0)
我不知道您是否能够完成实现,但是我能够在其他SO answer中使用现代C ++为同一问题编写解决方案。