After many years of coding scientific software in C++, I still can't seem to get used to exceptions and I've no idea when I should use them. I know that using them for controlling program flow is a big no-no, but otherwise than that... consider the following example (excerpt from a class that represents an image mask and lets the user add areas to it as polygons):
class ImageMask
{
public:
ImageMask() {}
ImageMask(const Size2DI &imgSize);
void addPolygon(const PolygonI &polygon);
protected:
Size2DI imgSize_;
std::vector<PolygonI> polygons_;
};
The default constructor for this class creates a useless instance, with an undefined image size. I don't want the user to be able to add polygons to such an object. But I'm not sure how to handle that situation. When the size is undefined, and addPolygon() is called, should I:
Most of the time I go either with 1) or 2) (depending on my mood), because it seems to me exceptions are costly, messy and simply overkill for such a simple scenario. Some insight please?
Use exceptions when the code that handles the error is separated from the code that detects the error by one or more intervening function calls. Consider whether to use error codes instead in performance-critical loops, when code that handles the error is tightly coupled to the code that detects it.
Exceptions should be used for exceptional situations outside of the normal logic of a program. In the example program an out of range value is likely to be fairly common and should be dealt with using normal if-else type logic. (See the programming exercises.)
Why is catch(Exception) almost always a bad idea ? Because exceptions if they are catched in the code, you need to handle them properly. And we cannot handle all types of exceptions. Some of the exceptions we cannot deal with it and they makes the application unstable like Thread abort exception.
Exceptions are meant for, well, exceptional cases. What this means is anytime there's a case where a code will cause abnormal failures, you should use exception handling.
The general rule is that you throw an exception when you cannot perform the desired operation. So in your case, yes, it does make sense to throw an exception when addPolygon is called and the size is undefined or inconsistent.
Silently returning is almost always the wrong thing to do. assert
is not a good error-handling technique (it is more of a design/documentation technique).
However, in your case a redesign of the interface to make an error condition impossible or unlikely may be better. For example, something like this:
class ImageMask
{
public:
// Constructor requires collection of polygons and size.
// Neither can be changed after construction.
ImageMask(std::vector<PolygonI>& polygons, size_t size);
}
or like this
class ImageMask
{
public:
class Builder
{
public:
Builder();
void addPolygon();
};
ImageMask(const Builder& builder);
}
// used like this
ImageMask::Builder builder;
builder.addPolygon(polyA);
builder.addPolygon(polyB);
ImageMask mask(builder);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With