@LokiAstariは正しいです。サイズ変更時のポインターに問題があることは明らかです。
わからないことがあります。あなたはオブジェクト プールを使用しているが、新しいステートメントが多すぎることに問題があると言っています。オブジェクト プールを使用している場合、それはまさに新しいステートメントを避けるためだと思いますよね?
ここに私の提案がありますが、私は専門家ではなく、通常は独自のアロケーターの実装を含むより良い解決策があるかもしれません (力の暗い側面..)。のようなコンテナーを使用できますstd::deque
。これにより、サイズ変更時のポインター/参照の有効性が保証されます。
多数のオブジェクト (プール) の最初のサイズ変更から開始し、必要に応じて後続のサイズ変更を手動で処理する (事前定義されたサイズのチャンクで容量を拡張する) か、必要があることがわかっている場合は新しいステートメントを受け入れることができます。 emplace_back メソッドを使用してください。
また、ID を使用してオブジェクトの挿入/削除を頻繁に行っているかどうかもわかりません。もしそうなら、あなたは使用を検討するかもしれませんstd::unordered_map
。
を使用した例を次に示しstd::deque
ます。
#include <iostream>
#include <deque>
#define POOL_RESERVE 1000
// Data storage for your object
struct MyObjectData
{
double some_data;
};
// Container returned by the factory
struct MyObject
{
typedef MyObjectData data_type;
unsigned id;
data_type* data;
MyObject(): id(0), data(0) {}
MyObject( const unsigned& id_, data_type* data_ ): id(id_), data(data_) {}
void set( const unsigned& id_, data_type* data_ )
{ id = id_; data = data_; }
};
// MyObject Pool
class MyObjectPool
{
public:
typedef MyObjectData data_type;
MyObjectPool(): count(0) { pool.resize(POOL_RESERVE); }
void get( const unsigned& id, MyObject& obj )
{
// Check requested index
if ( id >= count )
obj.set( 0, 0 );
else
obj.set( id, &pool[id] );
}
void create( MyObject& obj )
{
// Create new data container if needed
if ( count++ >= pool.size() ) pool.emplace_back();
// Return next available object
obj.set( count-1, &pool[count-1] );
}
private:
unsigned count;
std::deque<data_type> pool;
};
// MyObject factory
class MyObjectFactory
{
typedef MyObjectFactory self;
static MyObject local;
static MyObjectPool& get_instance()
{
static MyObjectPool pool;
return pool;
}
public:
static MyObject get( const unsigned& id )
{
self::get_instance().get(id,local);
return local;
}
static MyObject create()
{
self::get_instance().create(local);
return local;
}
};
// Define static variable
MyObject MyObjectFactory::local = MyObject();
// Usage example
int main()
{
MyObject a,b,c;
a = MyObjectFactory::create();
b = MyObjectFactory::create();
c = MyObjectFactory::get(1);
}