我有一个向量,我正在加载已知数量的元素 (N)。
该处理动态地创建新元素,这些元素被附加到向量中。
我预计要创建大约 2 * N 个附加元素,因此我将向量的大小调整为 3 * N。
如果额外的元素超过了,我想要一个程序中止,而不是向量的动态扩展。
有没有办法检测到,可以在 AIX/TRU64/Linux 之间移植?
我有一个向量,我正在加载已知数量的元素 (N)。
该处理动态地创建新元素,这些元素被附加到向量中。
我预计要创建大约 2 * N 个附加元素,因此我将向量的大小调整为 3 * N。
如果额外的元素超过了,我想要一个程序中止,而不是向量的动态扩展。
有没有办法检测到,可以在 AIX/TRU64/Linux 之间移植?
检测什么?矢量是否会调整大小?是否已经?
实现这一点的唯一真正方法是在自定义分配器或将元素添加到向量的函数中提供检查功能。
例如
template<class T>
void add_element(std::vector<T>& container, T const& v)
{
if (container.capacity()+1 >= 3*N)
{
// terminate/exception/whatever
}
container.push_back(v);
}
为什么要使用向量?向量的重点是在需要时动态扩展。
与其创建一个类来委托给向量,不如创建一个类来委托给一个简单的数组。让您的 push_back 检查大小并在需要时中止。
创建您自己的类,该类将委托给向量。并在您自己的 push_back 中检查大小。
如果您在编译时知道大小,也许使用 std::tr1::array (或boost::array)会是更好的选择。它保持固定大小并像 std::vector 一样检查访问。
但是,如果您只在运行时知道它,正如其他人所说,您应该将您的向量封装在一个具有特定函数的类中,这些函数将检查您想要的条件(例如通过断言)。
在最后一种方法中,我建议,如果您可以知道向量创建时的最大大小,则在封装类构造函数(或初始化函数)中保留( std::vector::reserve() )向量的最大大小. 这样,向量本身将不再进行内存操作(仅当向量元素构造函数/析构函数进行此类操作时)。然后,添加一个简单的断言来检查向量容量( std::vector::capacity() )在类的所有函数的开始和结束时从未改变,这将帮助您确保它的内存不会移动。
例如(假设 DATA_MAX_SIZE 是在某处定义的默认最大大小):
template< typename MyType >
class MyData
{
public:
MyData( unsigned long max_size = DATA_MAX_SIZE )
: m_max_size( max_size )
{ m_data.reserve( m_max_size ); }
void add( const MyType& value ) { check_capacity(); m_data.push_back( value ); check_capacity(); }
private:
std::vector< MyType > m_data;
const unsigned long m_max_size;
void check_capacity() { if( m_data.capacity() != m_max_size ) throw Exception("Useful error message here!" ); }
};
或类似的东西...
每次插入元素时,std 类都会使用一个分配器。您可以编写一个继承自 std::alocator 的新分配器,并添加您需要的所有类型的检查/跟踪。
(我以前这样做过,但我花了一段时间来编写工作代码。)