Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/136.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;最终类和切片习惯用法_C++_Final_Object Slicing - Fatal编程技术网

C++ C++;最终类和切片习惯用法

C++ C++;最终类和切片习惯用法,c++,final,object-slicing,C++,Final,Object Slicing,我碰巧浏览了mongoDB的源代码,发现了这个有趣的结构: class NonspecificAssertionException final : public AssertionException { public: using AssertionException::AssertionException; private: void defineOnlyInFinalSubclassToPreventSlicing() final {} }; 私有方法如何防止切片?我似乎

我碰巧浏览了mongoDB的源代码,发现了这个有趣的结构:

class NonspecificAssertionException final : public AssertionException {
public:
    using AssertionException::AssertionException;

private:
    void defineOnlyInFinalSubclassToPreventSlicing() final {}
};
私有方法如何防止切片?我似乎想不起这个问题


干杯,George

可以应用
最终
说明符的唯一成员函数是虚拟成员函数。在
AssertionException
或它自己的一个基类中,这个成员很可能被定义为

virtual void defineOnlyInFinalSubclassToPreventSlicing() = 0;
因此,层次结构中的所有类(除了最派生的类)都是抽象基类。不能创建抽象类的值(它们只能用作基)。因此,一个人可能不会意外地写

try {
    foo();
}
catch(AssertionException const e) { // oops catching by value
} 
如果
AssertionException
不是抽象的,则可以编写上述内容。但是当它是抽象的时候,编译器会向异常处理程序抱怨,迫使我们通过引用捕获。推荐的做法是参照捕捉

将成员(和类)标记为
final
可确保无法进一步派生。因此,当继承层次结构更改时,问题不会意外地再次出现。因为如果程序员添加了另一个类,并再次将
定义为final innalsubclasstopreventslicing
作为final,则会从编译器中引发错误,因为该成员已在基中声明为final。因此,他们必须从基类中删除实现,从而使其再次抽象


这是一个簿记系统。

链接不错(答案也不错)我认为你的答案不正确/至少有点让人困惑。虽然只有虚拟函数可以是最终函数,但它们不必重写纯虚拟函数。因此可以从
structbase{virtualvoidfoo(){}继承并用最终方法覆盖
foo
。人们仍然能够实例化
Base
final
说明符本身并不阻止只有一个已定义的重写,但如果程序员只向该方法的最终重写添加定义,则我们是安全的,因为同一方法不能有两个最终重写。Addedndum:继承是最终的,这一点也很重要,否则,可以毫无问题地从类继承,其中重写是最终的,不涉及重写,并且没有编译器会说任何话。tl;dr:这个成语很有用,但不是万能的。@n314159-我从来没有说过只有纯虚拟函数可以标记为final。我不知道你从哪里弄来的。人们不得不严重曲解我的答案才能得出这个结论。我在这里解释了可能的簿记机制,在防止切片的所有子类中,
的名称明确地表明了这一点。也许我误解得很严重,但对我来说,从你的回答中不清楚这仍然需要程序员的注意。特别是在您的前两段中,在我看来,通过只添加最后一个说明符,我们确保所有基类都是抽象的,但事实并非如此。我道歉,如果我是唯一一个这样认为的人,但我想补充我的观察,以防其他人也会误解。