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
If a virtual member function
vf
is declared in a classBase
and in a classDerived
, derived directly or indirectly fromBase
, a member functionvf
with the same name, parameter-type-list, cv-qualification, and ref-qualifier (or absence of same) asBase::vf
is declared, thenDerived::vf
is also virtual (whether or not it is so declared) and it overridesBase::vf
.
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
A virtual member function
C::vf
of a class objectS
is a final overrider unless the most derived class of whichS
is a base class subobject (if any) declares or inherits another member function that overridesvf
.
即如果你有一个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)`
};
标签:method-hiding,c,inheritance,virtual-functions,overriding 来源: https://codeday.me/bug/20190918/1811862.html