2016-04-15 39 views
6

纯粹的虚拟功能noexcept是好还是坏的做法?我一直认为我们不应该对它的实现类施加额外的限制,因为它们的实现应该是没有抛出的,因为这可能会导致修改实现和不必要的try catch块以防止异常转义。我认为实现应该决定函数是否可以标记为noexcept而不是异常规范应该决定实现?好的或坏的做法,使纯粹的虚拟功能noexcept

如果我在这里错了,有人能纠正我吗?

回答

8

noexcept不是关于实现,而是关于接口。由虚函数表示的抽象操作是否从根本上不能失败?然后使虚函数noexcept。如果操作可能会在理论上失败,即使没有你写的实现不能,也不要。

6

noexcept是成员函数规范的一部分,与返回类型,参数列表和const限定符相同。它在那里帮助用户的功能 - 显然,以功能的实施者为代价。

如果你需要给实施者更多的灵活性,同时为您的用户具有noexcept功能,使一对函数 - 与noexcept非虚公共职能,以及受保护的虚拟功能,无需noexcept。让公众noexcept函数调用虚拟实现,并处理异常,从它的调用者隐藏起来:

class Base { 
protected: 
    virtual void doSomethingImpl() = 0; 
public: 
    void doSomething() noexcept { 
     try { 
      doSomethingImpl(); 
     } catch(...) { 
      // Provide some handling here 
     } 
    } 
}; 

class Derived : public Base { 
    void doSomethingImpl() { 
     ... // Implementers have flexibility to throw here 
    } 
} 
+0

如果你需要使用这个结构我会说,那么有什么不对您的设计。为了能够正确处理实现的异常,基类需要知道其派生类太多。 – MicroVirus

+0

我同意MicroVirus基类不应该假设很多派生类,为什么我第一次总是犹豫,即使操作看起来太琐碎也不会放弃noexcept –

+0

@MicroVirus类似这样的东西可能是有用的作为防御实现,可能会意外地在情况下当你完全无法控制执行时。你可以做什么来处理异常*和*继续,因为没有任何事情发生,所以在那里的异常处理程序应该记录并帮助代码的其余部分优雅地终止。 – dasblinkenlight