本文介绍了什么是相反的c ++`override` /`final`说明符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 在c ++ 11中, 现在当A调用showPath()时,B显示painterPath而不是某个文件路径。 当然这是错误的,然后我应该将 B :: showPath()重命名为 B :: showPainterPath()并实现 B :: showPath()override 。 这里是一个编译现实世界的例子: #include< iostream> #define A_WITH_SHOWPATH class A { #ifdef A_WITH_SHOWPATH public: void setPath(std :: string const& filepath ){ std :: cout<< 文件路径设置为<文件路径< '。显示:\\\; showPath(); } //从外部调用,应显示文件路径 virtual void showPath(){ std :: cout< 显示未实现。 } #else //没有showPath()函数 #endif }; class B:public A { public: virtual void showPath()= 0; //从外部调用}; class C1:public B { public: virtual void showPath()override { std :: cout< C1显示绘图路径为graphic\\\; } }; class C2:public B { public: virtual void showPath()override { std :: cout< C2 shows painter path as widget\\\; } }; int main(){ B * b1 = new C1(); B * b2 = new C2(); std :: cout<< 应该说'C1显示画家路径为图形':\\\; b1-> showPath(); std :: cout<< --------------------------- \\\; std :: cout<< 应该说'C2显示画家路径为小部件':\\\; b2> showPath(); std :: cout<< --------------------------- \\\; #ifdef A_WITH_SHOWPATH std :: cout<< 应该给编译器警告\\\或说\文件路径设置为测试。显示它:\\\\和\显示未实现。\,\\\但不是\C1将绘图路径显示为图形\:\\\; b1-> setPath(Test); std :: cout<< #在B指针上调用setPath(\Test\)现在还显示了\\\#PainterPath,这不是预期的行为。 std :: cout<< #B中的setPath()函数应该被标记为从不覆盖基类的任何函数。\\\; std :: cout<< --------------------------- \\\; #endif return 0; } 运行它并查看文本输出。 作为参考,具有特定用例(PainterPath实例)的旧示例: https://ideone.com/6q0cPD (链接可能已过期)解决方案 这个答案是社区wiki,因为它结合了所有其他答案。 不,没有第一或 no_override 。 (answer) 覆盖 说明符。 Qt有一个(如果可用)的Q_DECL_OVERRIDErel =nofollow>宏 Q_DECL_OVERRIDE 。 > 如果不可用,至少用注释标记每个重写函数。 如果这样做, $ c> override : Clang现在具有 -Winconsistent-missing-override ,而较新的GCC具有 -Wsuggest-override 。 我不知道有VS2012标志。随意编辑。 您可以通过添加基类不知道的秘密来模仿所需的行为。 (answer) 这在非常具体的用例中是有用的,但通常打破虚拟性的概念(见其他答案的评论)。 如果你不拥有基类 如果您拥有基类, 您可以暂时向任何新的虚拟功能添加最后。 (answer) 代码编译后没有错误,你知道在任何派生类中都没有该名称和签名的函数,你可以再次删除 final 。 ...我想我会开始将虚拟函数标记为 DECL_FIRST 。也许在将来会有一个独立于编译器的方法来检查这个。 In c++11 the override specifier protects from not overriding an intended virtual base function (because the signatures do not match).The final specifier protects from unintentionally overriding a function in a derived class.=> Is there a specifier (something like maybe first or no_override) that protects from overriding an unknown base function?I'd like to get a compiler error when a virtual function was added to a base class with the same signature as an already existing virtual function in a derived class.EDIT 4: To keep this question simple and answers relevant, here is again theoriginal pseudo-codeabstract class B : A has private: virtual void fooHasBeenDone() = 0;class C : B implements private: virtual void fooHasBeenDone() override { react(); }Now class A gets a new private: virtual void fooHasBeenDone();But the new A::foo could be something different than the original B::foo.and a specific exampleabstract class B : A has virtual void showPath() = 0; meaing a PainterPathclass C : B implements virtual void showPath() override { mPath.setVisible(); }Now class A gets a new virtual void showPath(); meaning a file pathNow when A calls showPath(), B shows the painterPath instead of some file path.Of course this is wrong, and I should then rename B::showPath() to B::showPainterPath() and implement B::showPath() override as well. I'd just like to get informed by the compiler.Here is a compiling real-world example:#include <iostream>#define A_WITH_SHOWPATHclass A{#ifdef A_WITH_SHOWPATHpublic: void setPath(std::string const &filepath) { std::cout << "File path set to '" << filepath << "'. Display it:\n"; showPath(); } // to be called from outside, supposed to display file path virtual void showPath() { std::cout << "Displaying not implemented.\n"; }#else // has no showPath() function#endif };class B : public A{public: virtual void showPath() = 0; // to be called from outside};class C1 : public B {public: virtual void showPath() override { std::cout << "C1 showing painter path as graphic\n"; }};class C2 : public B {public: virtual void showPath() override { std::cout << "C2 showing painter path as widget\n"; }};int main() { B* b1 = new C1(); B* b2 = new C2(); std::cout << "Should say 'C1 showing painter path as graphic':\n"; b1->showPath(); std::cout << "---------------------------\n"; std::cout << "Should say 'C2 showing painter path as widget':\n"; b2->showPath(); std::cout << "---------------------------\n";#ifdef A_WITH_SHOWPATH std::cout << "Should give compiler warning\n or say \"File path set to 'Test'. Display it:\"\n and \"Displaying not implemented.\",\n but not \"C1 showing painter path as graphic\":\n"; b1->setPath("Test"); std::cout << "# Calling setPath(\"Test\") on a B pointer now also displays the\n# PainterPath, which is not the intended behavior.\n"; std::cout << "# The setPath() function in B should be marked to never override\n# any function from the base class.\n"; std::cout << "---------------------------\n";#endif return 0;}Run it and look at the text output.For reference, an older example with a specific use-case (PainterPath instance):https://ideone.com/6q0cPD (link may be expired) 解决方案 This answer is community wiki because it combines all other answers. Please upvote the specific answer that was helpful to you as well as this one.No, there is no specifier like first or no_override. (answer)You should use the override specifier as often as possible.Qt has a macro Q_DECL_OVERRIDE that expands to override, if available.If not available, at least mark each overriding function with a comment.If you do that, there are compiler flags that warn about a missing override:"Clang now has -Winconsistent-missing-override, and newer GCCs have -Wsuggest-override."I don't know of a VS2012 flag for this. Feel free to edit.You can mimic the desired behavior by adding a 'secret' that the base class cannot know. (answer)This is helpful in very specific use cases, but generally breaks the concept of virtuality (see comments to the other answers).If you don't own the base class and have a conflict (e.g. compiler warning), you will need to rename your virtual function in all derived classes.If you own the base class, you can temporarily add a final to any new virtual function. (answer)After the code compiles without errors, you know that no function of that name and signature exists in any derived class, and you can remove the final again.... I think I'll start marking first virtual functions as DECL_FIRST. Maybe in the future there will be a compiler-independent way of checking this. 这篇关于什么是相反的c ++`override` /`final`说明符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!
10-22 00:31