struct Object
{
Object(int type):type(type){}
virtual Object* clone()const = 0;
int type;
};
class OReal : public Object
{
public:
OReal():Object(0),location(DIRT),kill(UNKNOWN),alive(true){}
virtual OReal* clone()const{returnnew OReal(*this);}
Location location;
Kill kill;
bool alive;
};
typedef std::unordered_map<std::string,std::unique_ptr<Object>> HASH_TABLE;
class State
{
public:
State(){}
void addObject(const std::string& name,Object* obj){objects.insert(std::make_pair(name,std::unique_ptr<Object>(obj)) );}
//looks a little sloppy
Object* getObject(const std::string& name){auto it = objects.find(name);return (it==objects.end()) ? nullptr : it->second.get();}
const Object* getObject(const std::string& name)const{auto it = objects.find(name);return (it==objects.end()) ? nullptr : it->second.get();}
State(const State& s)
{
for(constauto& p : s.objects)
objects.insert(std::make_pair(p.first,std::unique_ptr<Object>(p.second->clone()) ));
}
State& operator=(const State& s)
{
assert(objects.size()==s.objects.size() && this!=&s);
for(constauto& p : s.objects)
{
auto it = objects.find(p.first);
assert(it!=objects.end());
it->second = std::unique_ptr<Object>(p.second->clone());
}
}
HASH_TABLE::iterator begin(){return objects.begin();}
HASH_TABLE::iterator end(){return objects.end();}
protected:
private:
HASH_TABLE objects;
};
int main()
{
State state = existingState; //no way to avoid allocation
//manipulate state
state = existingState; //better to copy existing data without allocating
}
Dynamically allocating memory is not efficient when assigning one State to another. Is there a better way to copy one state to another when they are the same size with the same types of derived Objects?
The first example you gave does not compile because unique_ptr cannot be assigned to an lvalue during the unordered_map copy. The second example works, but does not achieve good performance since the copy constructor will allocate new data for s when passed a lvalue. I am using copyTo to copy data without dynamically allocating data. One of my algorithms has a lot of state copying which is why I need it to only allocated data on the creation of a State instance and not every time an instance is set to another.
I am using copyTo to copy data without dynamically allocating data.
It looks like you'd mostly be using copyTo to partially copy an object and fail most of the time. Worse, you have no way of knowing what was successfully copied and what was not.
Again, if this is an issue for you (and it probably isn't) I would suggest the use of custom memory pools or a redesign of the class rather than a kludge of the sort you've presented.
The purpose of this entire class is to provide data storage for user defined data. A State instance is passed to user defined functions so that the user can retrieve his or her data by casting the pointers in the State to the appropriate derived class. There is not a way that I know of bypassing the necessity of using a container of pointers to user data to achieve this. To add to the complexity, some of my algorithms need to manipulate a state, perform some calculations, then reset the state back to the way it was before the computation, creating the necessity for efficient state copying. The format of the state should never change, so the copyTo function should never fail in any of my algorithms. The implementation of the State class will always require pointers of base classes and deep copying, no way around this. Also, I have no experience with custom memory pools. If you truly believe they are a good solution, then please elaborate on a design.