不确定何时在C++中使用异常

neu*_*rte 7 c++ exception

经过多年用C++编写科学软件的代码,我似乎还不习惯异常,我不知道何时应该使用它们.我知道使用它们来控制程序流是一个很大的禁忌,但除此之外......请考虑以下示例(摘自表示图像蒙版的类,并允许用户将区域添加为多边形):

class ImageMask
{
public:
    ImageMask() {}
    ImageMask(const Size2DI &imgSize);

    void addPolygon(const PolygonI &polygon);

protected:
    Size2DI imgSize_;
    std::vector<PolygonI> polygons_;
};
Run Code Online (Sandbox Code Playgroud)

此类的默认构造函数创建一个无用的实例,其图像大小未定义.我不希望用户能够将多边形添加到这样的对象.但我不知道如何处理这种情况.当大小未定义,并调用addPolygon()时,我应该:

  1. 默默地回来,
  2. 断言(imgSize_.valid)以使用此类检测代码中的违规并在发布之前修复它们,
  3. 抛出异常?

大部分时间我都选择1)或2)(取决于我的心情),因为在我看来,例外是昂贵的,混乱的,并且对于这样一个简单的场景来说简直过度.请问有些见解?

Kri*_*son 6

一般规则是当您无法执行所需操作时抛出异常.所以在你的情况下,是的,当调用addPolygon并且大小未定义或不一致时抛出异常是有意义的.

悄悄回归几乎总是错误的做法.assert不是一个好的错误处理技术(它更像是一种设计/文档技术).

但是,在您的情况下,重新设计界面以使错误条件不可能或不太可能更好.例如,像这样:

class ImageMask
{
public:
    // Constructor requires collection of polygons and size.
    // Neither can be changed after construction.
    ImageMask(std::vector<PolygonI>& polygons, size_t size);
}
Run Code Online (Sandbox Code Playgroud)

或者像这样

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);
Run Code Online (Sandbox Code Playgroud)