1

直觉告诉我抛出的类型越简单越好。抛出一个 int 比抛出一个指针更好,抛出一个结构比抛出一个类更好。在这种情况下,尽管有必要抛出一个带有动态分配成员的几乎完整的类。在堆中分配内存很方便,因为缓冲区可能会变得很长并且复制很昂贵;它不需要方法,因为它充当其他对象的控制/参数结构,但是在堆中构建它以抛出指向结构的指针和使用析构函数来清理内存都很方便。越简单越好,那么析构函数应该是虚拟的吗?省略 vtable或vtables完全不影响异常传递会更好吗?

从此结构派生类作为基类的优点是添加更多数据,而不是多态方法。指针可能会在异常点前几层被捕获并在模块之间传递,因此对象应尽可能干净,并尽可能降低复合错误的风险。

4

2 回答 2

1

仅当通过指向基类的指针删除对象时,才需要虚拟析构函数。对于异常类型,您不应该动态创建它们,而是按值抛出。所以不需要通过基类指针或其他方式删除它们,因此不需要虚拟析构函数。

话虽如此,与您提到的动态分配的数据相比,v-table 的成本很小,并且与抛出异常的成本相比,您应该始终优先考虑实用性而不是效率,除非已证明需要优化. 我建议您从中派生所有异常类型,std::exception以便您可以以统一的方式处理代码和标准库(和其他库)引发的错误。这已经有一个虚函数(what(),返回一个消息字符串)和一个虚析构函数。

于 2011-04-22T00:02:39.853 回答
1

看看 std::exception 并从中继承。

仅当您希望人们将该类用作基类时,析构函数才应该是虚拟的。

于 2011-04-21T22:51:48.493 回答