为什么不从std :: allocator继承 [英] Why not to inherit from std::allocator
问题描述
我创建了我自己的分配器,像这样:
I created my own allocator like so:
template<typename T>
class BasicAllocator
{
public:
typedef size_t size_type;
typedef ptrdiff_t difference_type;
typedef T* pointer;
typedef const T* const_pointer;
typedef T& reference;
typedef const T& const_reference;
typedef T value_type;
BasicAllocator() throw() {};
BasicAllocator (const BasicAllocator& other) throw() {};
template<typename U>
BasicAllocator (const BasicAllocator<U>& other) throw() {};
template<typename U>
BasicAllocator& operator = (const BasicAllocator<U>& other) {return *this;}
BasicAllocator<T>& operator = (const BasicAllocator& other) {return *this;}
~BasicAllocator() {}
pointer address (reference value) const {return &value;}
const_pointer address (const_reference value) const {return &value;}
pointer allocate (size_type n, const void* hint = 0) {return static_cast<pointer> (::operator new (n * sizeof (value_type) ) );}
void deallocate (void* ptr, size_type n) {::operator delete (static_cast<T*> (ptr) );}
template<typename U, typename... Args>
void construct (U* ptr, Args&& ... args) {::new (static_cast<void*> (ptr) ) U (std::forward<Args> (args)...);}
void construct (pointer ptr, const T& val) {new (static_cast<T*> (ptr) ) T (val);}
template<typename U>
void destroy (U* ptr) {ptr->~U();}
void destroy (pointer ptr) {ptr->~T();}
size_type max_size() const {return std::numeric_limits<std::size_t>::max() / sizeof (T);} /**return std::size_t(-1);**/
template<typename U>
struct rebind
{
typedef BasicAllocator<U> other;
};
};
但我想知道为什么我不应该继承 std :: allocator
。是因为它没有虚拟析构函数?我看到许多帖子说,一个应该创建自己的,而不是继承。我理解为什么我们不应该继承 std :: string
和 std :: vector
code> std :: allocator ?
But I want to know why I should never inherit from std::allocator
. Is it because it doesn't have a virtual destructor? I've seen many posts saying that one should create their own and not inherit. I understand why we shouldn't inherit std::string
and std::vector
but what is wrong with inheriting std::allocator
?
我可以继承我上面的类吗?
Can I inherit my class above? Or do I need a virtual destructor to do that?
为什么?
推荐答案
很多人都会在这个线程中发布你不应该从 std :: allocator
继承,因为它没有虚拟析构函数。他们将讨论多态性,切片和通过指针到基类删除,它们都不被分配器要求所允许,如标准的第17.6.3.5节[allocator.requirements]中所述。直到有人证明从 std :: allocator
派生的类不能满足这些要求之一,这是简单的货币心态。
A lot of people are going to post in this thread that you should not inherit from std::allocator
because it doesn't have a virtual destructor. They'll talk about polymorphism and slicing and deleting via pointer-to-base class, none of which are permitted by the allocator requirements as detailed in section 17.6.3.5 [allocator.requirements] of the standard. Until someone demonstrate that a class derived from std::allocator
fails to meet one of those requirements, it's simple cargo cult mentality.
也就是说,没有理由从C ++ 11中的 std :: allocator
派生。 C ++ 11的分配器检查引入了traits模板 std :: allocator_traits
位于分配器及其用户之间,并通过模板元编程为许多所需的功能提供合理的默认值。 C ++ 11中的最小分配器可以如下简单:
That said, there is little reason to derive from std::allocator
in C++11. C++11's overhaul of allocators introduced the traits template std::allocator_traits
to sit between an allocator and its users and provide reasonable defaults for many of the required features via template metaprogramming. A minimal allocator in C++11 can be as simple as:
template <typename T>
struct mallocator {
using value_type = T;
mallocator() = default;
template <class U>
mallocator(const mallocator<U>&) {}
T* allocate(std::size_t n) {
std::cout << "allocate(" << n << ") = ";
if (n <= std::numeric_limits<std::size_t>::max() / sizeof(T)) {
if (auto ptr = std::malloc(n * sizeof(T))) {
return static_cast<T*>(ptr);
}
}
throw std::bad_alloc();
}
void deallocate(T* ptr, std::size_t n) {
std::free(ptr);
}
};
template <typename T, typename U>
inline bool operator == (const mallocator<T>&, const mallocator<U>&) {
return true;
}
template <typename T, typename U>
inline bool operator != (const mallocator<T>& a, const mallocator<U>& b) {
return !(a == b);
}
编辑:正确使用 std :: allocator_traits
尚未完全出现在所有标准库中。例如,当使用GCC 4.8.1编译时, std :: list
上面的示例分配器不能正确工作 - std :: list
代码抱怨缺少成员,因为它尚未更新。
Proper use of std::allocator_traits
isn't fully present in all standard libraries yet. For example, the sample allocator above doesn't work correctly with std::list
when compiled with GCC 4.8.1 - the std::list
code complains about missing members since it hasn't been updated yet.
这篇关于为什么不从std :: allocator继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!