What is the best way to empty an object?

Viewed 123

Say I have the following code(this is just an example, obviously not practical):

std::list <Object> objects;

Object cur_object;
for(int i = 0; i < 11; i++){
    switch(i){
        case 0:
            cur_object.foo = true;
            break;
        case 5:
        case 10:
            objects.push_back(cur_object);
            Object cur_object; //Line in question
            break;
        default:
            cur_object.bar = i;
            break;
    }
}

What is the most effective and efficient way to "reset" the cur_object for the next pass. For example, I don't believe cur_object = *new Object is correct. Would it be best for the class to have a reset method?

Solution:

After looking at perf for the suggested methods for my use case they were very close, all within 0.5% of eachother, but the accepted answer, the objects.emplace_back() method was the most efficient.

2 Answers

You could circumvent that completely by simply keeping that extra object at the end of the list:

std::list<Object> objects;
objects.emplace_back();    // temporary object is at the end of objects

for(int i = 0; i < 11; i++){
    switch(i){
        case 0:
            objects.back().foo = true;
            break;
        case 5:
        case 10:
            objects.emplace_back(); // current becomes stored, add new temporary
            break;
        default:
            objects.back().bar = i;
            break;
    }
}

objects.pop_back(); // get rid of temporary

pop_back is cheap enough that it shouldn't be a problem to do it once for the entire collection, and you don't need to be concerned with moving the temporary into the list and resetting it.

You can use placement new to construct a new object within the storage of the old object. However, to be on the defined side of behavior, you need to turn curObject into a pointer:

char storage[sizeof(Object)];    //this is where we will store the object
Object* curObject = new(storage) Object();    //construct an Object within the storage

...

curObject->~Object();    //explicitly call destructor to tear down the old object
curObject = new(storage) Object();    //the storage can be reused now

The advantage of this approach is that it works even when Object has its assignment operators deleted.

Related