所以,是的,我知道“你不应该从性病容器中派生出来”,但现在它更多的是我头脑中的哲学规则,而不是一个技术规则。我再次搜索的一个基本原因,但找不到它。
因此,如果下面的内容没有根本问题,如果我们不考虑性能问题,那么我可以对此进行一次简单的代码回顾吗?
namespace growth
{
template<size_t N>
class linear
{
public:
static_assert(N != 0, "Linear growth requires positive factor");
static size_t grow(size_t size, size_t capacity)
{
return (size == capacity) ? capacity + N : capacity;
}
};
template<typename Ratio = std::ratio<2, 1>>
class geometric
{
public:
static_assert(Ratio::num > Ratio::den, "Geometric growth requires ratio greater than 1");
static size_t grow(size_t size, size_t capacity)
{
return (size == capacity) ? std::max((size_t)(capacity * (Ratio::num / (double)Ratio::den)), capacity + 1) : capacity;
}
};
}
template<typename T, typename Growth, class Allocator = std::allocator<T>>
class custom_growth_vector : public std::vector<T, Allocator>
{
public:
using vector = std::vector<T, Allocator>;
using vector::vector;
void push_back(T&& value)
{
vector::reserve(Growth::grow(vector::size(), vector::capacity()));
vector::push_back(value);
}
// Also replace emplace_back, insert, etc.
};
// ...
// Grows by 50% rather than double when size == capacity.
custom_growth_vector<int, growth::geometric<ratio<3, 2>>> cgvi;发布于 2016-04-01 22:29:35
让我们首先尝试对继承的情况做一个简短的总结。
只要您只是创建/使用/销毁您类型的对象,它从标准容器中公开继承这一事实就不会导致问题。
如果您有指向派生类对象的基类的指针(或引用),并且通过指向基类的指针破坏该对象,则会出现问题。
std::vector<int> *t = new custom_growth_vector<int, growth::geometric<ratio<3, 2>>>;
// ...
delete t; // This causes undefined behavior不幸的是,您无法在类中阻止这种情况--公共继承的部分定义是它允许隐式转换到基类。
除此之外:
使用您的growth::linear类意味着,您以这种方式创建的任何vector都不再满足对push_back进行摊还不变复杂性的要求。在另一个方向上,这确实意味着通过增长矢量而“浪费”的空间数量被限制在一个常数上。
push_back通常会重载const引用和rvalue引用,尽管这可能只是您尚未提供的另一个成员函数。
我想,我最终看到的最大问题是一个相当简单的问题,那就是这个问题的真正意义是什么。大多数系统使用虚拟内存,这通常意味着,即使您认为您在按照几何级数扩展分配,系统也很有可能为您的数据分配一个算术序列之后的实际存储空间,几乎不管您试图做什么。
https://codereview.stackexchange.com/questions/124492
复制相似问题