C++ final class 和切片习语
C++ final class and slicing idiom
我碰巧浏览了 mongoDB 的源代码,发现了这个有趣的结构:
class NonspecificAssertionException final : public AssertionException {
public:
using AssertionException::AssertionException;
private:
void defineOnlyInFinalSubclassToPreventSlicing() final {}
};
私有方法如何防止切片?问题case好像想不起来了
干杯,乔治
唯一可以应用 final
说明符的成员函数是虚拟成员函数。很可能在 AssertionException
或者它自己的基 class 中,这个成员被定义为
virtual void defineOnlyInFinalSubclassToPreventSlicing() = 0;
因此,层次结构中的所有 classes 除了最派生的那些都是抽象基础 classes。一个人可能无法创建抽象 classes 的值(它们只能作为基础)。因此,人们可能不会不小心写
try {
foo();
}
catch(AssertionException const e) { // oops catching by value
}
如果AssertionException
不是抽象的,可以写成上面的。但是当它是抽象的时,编译器会抱怨那个异常处理程序,迫使我们通过引用进行捕获。并且通过引用捕获是推荐的做法。
将成员(和 class)标记为 final
可确保无法进一步派生。因此,当继承层次结构更改时,问题不会意外地重新出现。因为添加另一个 class 并再次将 defineOnlyInFinalSubclassToPreventSlicing
定义为 final 的程序员会导致编译器出错,因为该成员已在基类中声明为 final。因此,他们将不得不从基础中删除实现 class,从而使其再次抽象。
这是一个簿记系统。
我碰巧浏览了 mongoDB 的源代码,发现了这个有趣的结构:
class NonspecificAssertionException final : public AssertionException {
public:
using AssertionException::AssertionException;
private:
void defineOnlyInFinalSubclassToPreventSlicing() final {}
};
私有方法如何防止切片?问题case好像想不起来了
干杯,乔治
唯一可以应用 final
说明符的成员函数是虚拟成员函数。很可能在 AssertionException
或者它自己的基 class 中,这个成员被定义为
virtual void defineOnlyInFinalSubclassToPreventSlicing() = 0;
因此,层次结构中的所有 classes 除了最派生的那些都是抽象基础 classes。一个人可能无法创建抽象 classes 的值(它们只能作为基础)。因此,人们可能不会不小心写
try {
foo();
}
catch(AssertionException const e) { // oops catching by value
}
如果AssertionException
不是抽象的,可以写成上面的。但是当它是抽象的时,编译器会抱怨那个异常处理程序,迫使我们通过引用进行捕获。并且通过引用捕获是推荐的做法。
将成员(和 class)标记为 final
可确保无法进一步派生。因此,当继承层次结构更改时,问题不会意外地重新出现。因为添加另一个 class 并再次将 defineOnlyInFinalSubclassToPreventSlicing
定义为 final 的程序员会导致编译器出错,因为该成员已在基类中声明为 final。因此,他们将不得不从基础中删除实现 class,从而使其再次抽象。
这是一个簿记系统。