Reputation: 515
std::vector<Circle*> circles
for(int i=0; i<circles.size(); i++) // 1
delete circles[i];
for(auto & circle : circles) // 2
delete circle;
for(Circle * circle : circles) // 3
delete circle;
for(Circle *& circle : circles){ // 4
delete circle;
If I write it the first way, CLion IDE suggests me to use the second way so I guess they're the same. I'm not really sure why there's a reference next to auto and if any of methods 3 or 4 are correct as well? I would guess 4 is also same as 1 and 2.
Upvotes: 2
Views: 100
Reputation: 85286
For completeness, there's one more way:
for(auto circle : circles)
delete circle;
Now, all these ways in this example are equivalent and will do the job of deleting circles
elements equally well.
Having a reference to a pointer doesn't matter (the reference is "unwrapped" in expressions - in technical terms an lvalue-to-rvalue conversion), in all cases the actual pointer value is passed to delete
.
The IDE seems to be suggesting the most idiomatic way of writing a range-based for loop:
for(auto & elem : collection)
This is usually the safest form; this way if collection
contains large objects, they will be iterated by reference, without unnecessary copying. It doesn't matter in our case as a trivial type like a pointer can be easily copied.
P.S. As others have noted, in modern C++ we try to avoid new
and delete
and use value semantics and smart pointers instead. So something simple like std::vector<Circle> circles
could be all that's needed, or if pointers are required, std::vector<std::unique_ptr<Circle>> circles
. No manual cleanup necessary in both cases.
Upvotes: 4