所以我使用从std::vector派生的容器已经有一段时间了。也许由于几个原因,这是一个糟糕的设计决策,这里已经广泛讨论了是否应该这样做的问题:
Thou shalt not inherit from std::vector
Subclass/inherit standard containers?
Is there any real risk to deriving from the C++ STL containers?
Is it okay to inherit implementation from STL containers, rather than delegate?
我确信我错过了…的一些讨论但在链接中可以找到这两种观点的合理论点。据我所知,“因为~vector()是非虚的”是你不应该从stl容器继承的“规则”的基础。但是,如果我查看一下g++ 4.9.2中std::vector的实现,我会发现std::vector继承自_Vector_base,而_Vector_base是一个非虚拟析构函数。
template<typename _Tp, typename _Alloc = std::allocator<_Tp> >
class vector : protected _Vector_base<_Tp, _Alloc>
{
...
~vector() _GLIBCXX_NOEXCEPT
{ std::_Destroy(this->_M_impl._M_start, this->_M_impl._M_finish,
_M_get_Tp_allocator()); }
...
}
其中:
template<typename _Tp, typename _Alloc>
struct _Vector_base
{
...
~_Vector_base() _GLIBCXX_NOEXCEPT
{ _M_deallocate(this->_M_impl._M_start, this->_M_impl._M_end_of_storage
- this->_M_impl._M_start); }
...
}
因此,gcc 4.9.2的std::vector实现继承了具有非虚析构函数的基类。这让我相信这是一种可以接受的做法。为什么这是可以的?这种做法不危险的具体条件是什么?
发布于 2014-12-07 02:24:40
因为用户代码尝试销毁_Vector_base
是非法的,因为它是stdlib内部类型。这可以防止析构函数出现任何问题。你就不能说同样的话了。
简而言之,标准库内部是一个特例,无论是在语言规则方面,还是在对它们合理的方面。你不能从他们的所作所为来概括你自己的代码。
发布于 2014-12-07 06:06:58
只是一个数据点。
在“C++之旅”中,Bjarne Stroustrup定义了一个从std::vector<T>.
派生的类模板,目的是在使用operator []时进行范围检查。其他一切都委托给基类。
发布于 2014-12-07 02:32:11
没有这样的规则“不继承具有非虚拟析构函数的基类”。如果有一条规则,那就是:“如果你有一个虚方法,就把你的析构函数设为虚的,这也意味着不要继承具有非虚析构函数的基类”。如果你遵循这个,继承stl容器是可以的。
似乎一些编译器架构师也同意这一点。字面上有一个警告,说明它-供参考:What does 'has virtual method ... but non-virtual destructor' warning mean during C++ compilation?
https://stackoverflow.com/questions/27334801
复制相似问题