c – 覆盖虚拟功能和隐藏非虚拟功能有什么区别?
给定以下代码片段,函数调用有何不同?什么是隐藏功能?什么是功能重写?它们如何与函数重载相关?两者有什么区别?我在一个地方找不到这些的好描述,所以我在这里问我所以我可以巩固这些信息.
class Parent { public: void doA() { cout << "doA in Parent" << endl; } virtual void doB() { cout << "doB in Parent" << endl; } }; class Child : public Parent { public: void doA() { cout << "doA in Child" << endl; } void doB() { cout << "doB in Child" << endl; } }; Parent* p1 = new Parent(); Parent* p2 = new Child(); Child* cp = new Child(); void testStuff() { p1->doA(); p2->doA(); cp->doA(); p1->doB(); p2->doB(); cp->doB(); } 解决方法
什么是隐藏功能?
……是隐藏名称的一种形式.一个简单的例子: void foo(int); namespace X { void foo(); void bar() { foo(42); // will not find `::foo` // because `X::foo` hides it } } 这也适用于基类中的名称查找: class Base { public: void foo(int); }; class Derived : public Base { public: void foo(); void bar() { foo(42); // will not find `Base::foo` // because `Derived::foo` hides it } }; 什么是功能重写? 这与虚函数的概念有关. [class.virtual] / 2
class Base { private: virtual void vf(int) const &&; virtual void vf2(int); virtual Base* vf3(int); }; class Derived : public Base { public: // accessibility doesn't matter! void vf(int) const &&; // overrides `Base::vf(int) const &&` void vf2(/*int*/); // does NOT override `Base::vf2` Derived* vf3(int); // DOES override `Base::vf3` (covariant return type) }; 调用虚函数时,最终的覆盖变得相关:[class.virtual] / 2
即如果你有一个S类型的对象,那么最终的覆盖是你在遍历S的类层次结构回到它的基类时看到的第一个覆盖.重要的是,函数调用表达式的动态类型用于确定最终的覆盖: Base* p = new Derived; p -> vf(); // dynamic type of `*p` is `Derived` Base& b = *p; b . vf(); // dynamic type of `b` is `Derived` 覆盖和隐藏有什么区别? 实质上,基类中的函数总是被派生类中的同名函数隐藏;无论派生类中的函数是否覆盖基类的虚函数: class Base { private: virtual void vf(int); virtual void vf2(int); }; class Derived : public Base { public: void vf(); // doesn't override,but hides `Base::vf(int)` void vf2(int); // overrides and hides `Base::vf2(int)` }; 要查找函数名称,请使用表达式的静态类型: Derived d; d.vf(42); // `vf` is found as `Derived::vf()`,this call is ill-formed // (too many arguments) 它们如何与函数重载相关? 由于“函数隐藏”是一种名称隐藏形式,如果隐藏了函数的名称,则所有重载都会受到影响: class Base { private: virtual void vf(int); virtual void vf(double); }; class Derived : public Base { public: void vf(); // hides `Base::vf(int)` and `Base::vf(double)` }; 对于函数重写,只覆盖具有相同参数的基类中的函数;你当然可以重载一个虚函数: class Base { private: virtual void vf(int); virtual void vf(double); void vf(char); // will be hidden by overrides in a derived class }; class Derived : public Base { public: void vf(int); // overrides `Base::vf(int)` void vf(double); // overrides `Base::vf(double)` }; (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |