Hi Martin,
I've seen this before, but it didn't stick. To get really picky for a
moment, would size_t or streamsize or something be more fitting than
int?
(thanks to Buster for pointing out the related fix in the C++ standard)
What are some pitfalls that this abstraction would promote?
This might be seen as a matter of taste.
However, creating a new name (PNode) without actually
simplifying anything is more error prone than anything else.
I would have expected PNode to be a Node*, not a const Node*.
Other than the 'less typing' argument, is there any reason
not to just use "const Node*" instead of "PNode" ? (i.e. for clarity)
Did you intend levelPool to be of a class of my own creation which
takes ownership of inserted pointers? If not, what's the difference
to the other quoted option?
No: I intended it to be a standard container such as deque.
The aim is to keep using a container of pointers, which you
can efficiently sort, shuffle, move etc.
However, instead of allocating the pointed-to objects
on the heap, you allocate them within a separate container.
When this separate container is destroyed, you get
the equivalent of garbage collection for free.
Would it suffice to wrap the current ctor body in a try block and
then in the handler, put the above dtor code and rethrow? Or maybe
build a local structure and assign that to the member if all is well
in the end?
Adding a try..catch block usually isn't the simplest solution,
but it is an option. Alternatively, you could try using
a custom-made 'owning' container of pointers.
But I think the previously mentioned alternatives are better.
Level* pl = new Level();
try {
levels_.push_back(pl);
} catch(...) {
delete pl;
throw;
}
Is that reasonable?
It would seem easier to call levels_.reserve(...),
ensuring that no exception will be thrown.
In good (= reliable & maintainable) C++ code, uses of
try..catch blocks are be limited to locations where
errors are actually handled (or converted).
Rethrowing the same exception often hints at bad
design - IMHO.
Cheers,
Ivan